我尝试在SwiftUI中构建相当复杂的View。结构是这样的:
struct ContentView<V: SpaceVertexProtocol>: View where V.Coord.Axis : StyledAxisProtocol{
@EnvironmentObject var environment: ViewsEnvironments<V>
@ObservedObject var global: GlobalEnvironment<V>
var body: some View {
// It will be HStack, for a while just one view
SpaceVerticesView(coordinates: $global.coordinates, vertices: $global.vertices)
.padding(EdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5))
.environmentObject(environment.spaceVerticesView)
}
}
public struct SpaceVerticesView<V:SpaceVertexProtocol> : View {
...
@Binding var coordinates : [V.Coord]
...
func updateCoordnates {
coordinates = ... // yes, this updates view, they're changed by `coordinates[index].at = something`
}
public var body: some View {
...
SpotsView(coordinates: $coordinates,....)
...
}
struct SpotsView<V:SpaceVertexProtocol> : View {
...
@Binding var coordinates: [V.Coord]
var spots: [SpotView<V>] {
var result: [SpotView<V>] = []
...
//counts and adds views initiated as:
result.append(SpotView(coordinates: $coordinates,...)
...
return result
}
var body: some View {
return ZStack {
// makes some SpotView on top
ForEach(0..<spots.count, id: \.self) { index in
return self.spots[index]
}
}
}
和另外两个级别(总是coordinates
作为$coordinates
传递给@Binding
变量。
在最深的视图中,var body
返回Shape
var body {
...
return spotShape
.contentShape(spotShape.clickArea).offset(x: 0, y: shift)
.onTapGesture {
print ("Tap gesture:",self)
print (self.coordinates, targetCoordinates)
self.coordinates = targetCoordinates
我可以看到coordinates
已更新,但视图未重绘。
如果单击clickArea
之外的位置,则会触发SpaceVerticesView.updateCoordinates(...)
,coordinates
会更改,并且视图会重绘。 Shape
@Binding
无效吗?为什么没有反应?
当coordinates
是@EnvironmentObject
的一部分时,就可以了。