重用视图而不将绑定传递给每个中间视图
Reuse views without passing bindings to every intermediate view
在 swiftUI 中,创建一次性视图相当简单,其相应的状态嵌入到关联的视图模型中。但是我怎样才能使用例如view1 的自定义文本字段,嵌入在更复杂的 view2 中,在 view3 中哪个是最终视图?我知道我可以将 view1 的文本字段文本作为绑定传递给 view2,然后再传递给 view3。但是一旦 UI 变得复杂,就需要传递大量绑定,尤其是在存在大量中间视图的情况下。我如何在不将 view1 的文本字段文本状态传递给每个中间视图的情况下重用它,以及如何将其理想地实现到 view3 的视图模型中?
简单示例结构:
视图 1:
struct SwiftUIView3: View {
@Binding var textInTextField: String
var body: some View {
TextField("Test", text: $textInTextField)
}
}
视图 2:
struct SwiftUIView2: View {
@Binding var textInTextField: String
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 15)
.frame(height: 200)
.foregroundColor(.blue)
SwiftUIView3(textInTextField: $textInTextField)
}
}
}
视图 3:
struct ContentView: View {
@State private var textInTextField = ""
var body: some View {
VStack {
SwiftUIView2(textInTextField: $textInTextField)
Text(textInTextField)
}
}
}
这是可能的解决方案。使用 Xcode 11.4 / iOS 13.4
测试
想法是使用视图模型作为环境对象注入到子层次结构中,因此在任何级别的子视图中都可以提取它并使用,顶层视图将相应地更新`因为它持有观察到的视图模型对象。
struct SwiftUIView3: View {
@EnvironmentObject var eo: TextViewModel // << auto-associated
var body: some View {
TextField("Test", text: $eo.textInTextField)
}
}
struct SwiftUIView2: View {
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 15)
.frame(height: 200)
.foregroundColor(.blue)
SwiftUIView3() // << nothing to pass
}
}
}
class TextViewModel: ObservableObject {
@Published var textInTextField = ""
}
struct ContentView: View {
@ObservedObject private var vm = TextViewModel()
var body: some View {
VStack {
SwiftUIView2() // << nothing to pass
Text(vm.textInTextField)
}.environmentObject(vm) // << inject into hierarchy
}
}
在 swiftUI 中,创建一次性视图相当简单,其相应的状态嵌入到关联的视图模型中。但是我怎样才能使用例如view1 的自定义文本字段,嵌入在更复杂的 view2 中,在 view3 中哪个是最终视图?我知道我可以将 view1 的文本字段文本作为绑定传递给 view2,然后再传递给 view3。但是一旦 UI 变得复杂,就需要传递大量绑定,尤其是在存在大量中间视图的情况下。我如何在不将 view1 的文本字段文本状态传递给每个中间视图的情况下重用它,以及如何将其理想地实现到 view3 的视图模型中?
简单示例结构:
视图 1:
struct SwiftUIView3: View {
@Binding var textInTextField: String
var body: some View {
TextField("Test", text: $textInTextField)
}
}
视图 2:
struct SwiftUIView2: View {
@Binding var textInTextField: String
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 15)
.frame(height: 200)
.foregroundColor(.blue)
SwiftUIView3(textInTextField: $textInTextField)
}
}
}
视图 3:
struct ContentView: View {
@State private var textInTextField = ""
var body: some View {
VStack {
SwiftUIView2(textInTextField: $textInTextField)
Text(textInTextField)
}
}
}
这是可能的解决方案。使用 Xcode 11.4 / iOS 13.4
测试想法是使用视图模型作为环境对象注入到子层次结构中,因此在任何级别的子视图中都可以提取它并使用,顶层视图将相应地更新`因为它持有观察到的视图模型对象。
struct SwiftUIView3: View {
@EnvironmentObject var eo: TextViewModel // << auto-associated
var body: some View {
TextField("Test", text: $eo.textInTextField)
}
}
struct SwiftUIView2: View {
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 15)
.frame(height: 200)
.foregroundColor(.blue)
SwiftUIView3() // << nothing to pass
}
}
}
class TextViewModel: ObservableObject {
@Published var textInTextField = ""
}
struct ContentView: View {
@ObservedObject private var vm = TextViewModel()
var body: some View {
VStack {
SwiftUIView2() // << nothing to pass
Text(vm.textInTextField)
}.environmentObject(vm) // << inject into hierarchy
}
}