在swiftUI中,创建具有相应状态的一次性视图非常简单,该视图嵌入在关联的视图模型中。但是我该如何使用例如view1的自定义文本字段,它嵌入在更复杂的view2中,在view3中,这是最终视图?我知道我可以将view1的文本字段的文本作为绑定传递给view2,然后传递给view3。但是,一旦UI变得复杂,就需要传递很多绑定,尤其是在有很多中间视图的情况下。如何在不将view1的文本字段文本状态传递给每个中间视图的情况下重用view1?如何在理想情况下将其实现到view3的视图模型中?
简单的示例结构:
View1:
struct SwiftUIView3: View {
@Binding var textInTextField: String
var body: some View {
TextField("Test", text: $textInTextField)
}
}
View2:
struct SwiftUIView2: View {
@Binding var textInTextField: String
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 15)
.frame(height: 200)
.foregroundColor(.blue)
SwiftUIView3(textInTextField: $textInTextField)
}
}
}
View3:
struct ContentView: View {
@State private var textInTextField = ""
var body: some View {
VStack {
SwiftUIView2(textInTextField: $textInTextField)
Text(textInTextField)
}
}
}
答案 0 :(得分:0)
这是可能的解决方案。使用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
}
}