[编辑:请注意 @ObjectBinding 不再存在;相反,您可以使用 @State 将实例变量标记为在更改时需要刷新视图。]
当视图声明一个@State
或@Binding
变量时,它的值必须显式地从视图的父级传递。因此,如果您有一个较长的视图层次结构,其中一些来自顶部的数据在底部使用,您必须对该层次结构的每个级别进行编码以了解并传递数据。
在 29:00 的评论中,他将此与在子视图中使用 @EnvironmentVariable 进行了对比,后者在整个层次结构中搜索该数据。这意味着任何不明确需要数据的视图都可以有效地忽略它。注册一个变量只需要完成一次(通过.environmentObject(_)
一个视图)。
这是一个人为的例子。给定一些符合的数据类型ObservableObject
,
class SampleData: ObservableObject {
@Published var contents: String
init(_ contents: String) {
self.contents = contents
}
}
考虑这个视图层次结构:
struct ContentView: View {
@State private var data = SampleData("sample content")
var body: some View {
VStack {
StateViewA(data: self.data)
EnvironmentViewA()
.environmentObject(self.data)
}
}
}
struct StateViewA: View {
@State var data: SampleData
var body: some View {
StateViewB(data: self.data)
}
}
struct StateViewB: View {
@State var data: SampleData
var body: some View {
Text(self.data.contents)
}
}
struct EnvironmentViewA: View {
var body: some View {
EnvironmentViewB()
}
}
struct EnvironmentViewB: View {
@EnvironmentObject var data: SampleData
var body: some View {
Text(self.data.contents)
}
}
结果ContentView
将是显示同一段文本的两个视图。首先,StateViewA
必须将数据传递给它的孩子(即模型从“跳到跳”传递),而在第二个中,EnvironmentViewA
根本不需要知道数据。