SwiftUI中的更新路径

问题描述

我有一个带有图表的SwiftUI视图,该图表是使用路径和entries数组中的数据制成的。

代码

struct TodayChartView: View {
    var body: some View {
            GeometryReader { reader in
                    Path { p in
                            for i in 1..<entries.count {
                                p.move(to: CGPoint(x: entries[i-1].x,entries[i-1].y: y))
                                p.addLine(to: CGPoint(entries[i].x: x,entries[i].y: y))
                            }
                        }
                    }.stroke(Color.blue,style: strokeStyle(linewidth: 3,lineCap: .round,lineJoin: .round))
                }
}

用户在另一个视图中按下按钮时,新条目将添加entries,并且我想在“路径”上显示它。因此,基本上,我需要以某种方式触发重绘它。有什么办法可以实现?

解决方法

尝试这个

    Path { p in
            for i in 1..<entries.count {
                p.move(to: CGPoint(x: entries[i-1].x,entries[i-1].y: y))
                p.addLine(to: CGPoint(entries[i].x: x,entries[i].y: y))
            }
        }
    }.stroke(Color.blue,style: StrokeStyle(lineWidth: 3,lineCap: .round,lineJoin: .round))
    .id(entries)     // << here !!
,

entries作为参数传递给TodayChartView。在entries中将@State var作为ContentView的情况下,只要TodayChartView发生变化,entries就会被重绘。

这是一个完整的示例(已在Xcode 11.7中进行了测试):

struct TodayChartView: View {
    let entries: [CGPoint]
    
    var body: some View {
        // GeometryReader { reader in
            Path { p in
                for i in 1..<self.entries.count {
                    p.move(to: CGPoint(x: self.entries[i-1].x,y: self.entries[i-1].y))
                    p.addLine(to: CGPoint(x: self.entries[i].x,y: self.entries[i].y))
                }
            }
            .stroke(Color.blue,lineJoin: .round))
        // }
    }
}

struct ContentView: View {
    @State private var entries: [CGPoint] = [CGPoint(x: 150,y: 150)]
    
    var body: some View {
        VStack(spacing: 20) {
            Button("Add Point") {
                let x = CGFloat.random(in: 0...300)
                let y = CGFloat.random(in: 0...300)
                self.entries.append(CGPoint(x: x,y: y))
            }
            TodayChartView(entries: self.entries)
                .frame(width: 300,height: 300)
        }
    }
}

注意:您的TodayChartView当前未使用GeometryReader,因此我已将其注释掉。