View 重用视图,而不向每个中间视图传递绑定

View 重用视图,而不向每个中间视图传递绑定,view,binding,swiftui,state,reusability,View,Binding,Swiftui,State,Reusability,在swiftUI中,创建单次使用视图并将其相应的状态嵌入到关联的视图模型中相当简单。但是,如何使用view1的自定义文本字段(嵌入到更复杂的view2中),以及view3(最终视图)中?我知道我可以将view1的文本字段的文本作为绑定传递给view2,然后再传递给view3。但是一旦UI变得复杂,就需要传递很多绑定,特别是如果有很多中间视图的话。如何重用view1而不将其textfield文本状态传递给每个中间视图,以及如何在view3的视图模型中理想地实现这一点 简单示例结构: 视图1: st

在swiftUI中,创建单次使用视图并将其相应的状态嵌入到关联的视图模型中相当简单。但是,如何使用view1的自定义文本字段(嵌入到更复杂的view2中),以及view3(最终视图)中?我知道我可以将view1的文本字段的文本作为绑定传递给view2,然后再传递给view3。但是一旦UI变得复杂,就需要传递很多绑定,特别是如果有很多中间视图的话。如何重用view1而不将其textfield文本状态传递给每个中间视图,以及如何在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
    }
 }

struct SwiftUIView3:视图{

@EnvironmentObject var eo:TextViewModel/这里是可能的解决方案。使用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
    }
 }

struct SwiftUIView3:视图{
@EnvironmentObject变量eo:TextViewModel//