在 SwiftUI MVVM 中的子视图和父视图之间共享值

Posted

技术标签:

【中文标题】在 SwiftUI MVVM 中的子视图和父视图之间共享值【英文标题】:Share value between child and parent view in SwiftUI MVVM 【发布时间】:2020-05-17 18:59:29 【问题描述】:

我正在尝试使用 SwiftUI 和 MVVM 架构编写应用程序。我了解视图模型更改时视图如何自动更新,但我不知道如何在父视图中访问该视图模型。例如,我有一个包含红色背景文本字段的视图:

class CustomTextFieldViewModel: ObservableObject 
    @Published var text: String = "abc"


struct CustomTextField: View 
    @ObservedObject var viewModel: CustomTextFieldViewModel

    var body: some View 
        ZStack 
            Color.red
                .frame(height: 50)
            TextField("Enter text...", text: $viewModel.text)
        
    

然后我的主要内容视图包含此 CustomTextField 的实例以及应该引用文本字段文本的 Text:

class ContentViewModel: ObservableObject 
    @Published var textFieldModel = CustomTextFieldViewModel()


struct ContentView: View 
    @ObservedObject var viewModel = ContentViewModel()
    var body: some View 
        VStack 
            CustomTextField(viewModel: $viewModel.textFieldModel)
            TextField("type", text: $viewModel.textFieldModel.text)
        
    

当我第一次启动应用程序时,文本标签确实显示了“abc”的初始值,但是当我在文本字段中输入时,它不会更新。 我怎样才能“同步”这两者?

【问题讨论】:

【参考方案1】:

这里是修复

struct ContentView: View 
    @ObservedObject var viewModel = ContentViewModel()
    var body: some View 
        VStack 
            CustomTextField(viewModel: viewModel.textFieldModel) // << fix !!
            Text("\(viewModel.textFieldModel.text)")
        
    

【讨论】:

我最终修复了它。不仅如此,CustomTextField 中的viewModel 也应该是@Binding。【参考方案2】:

我最终通过这样做来修复它:

class ContentViewModel: ObservableObject 
    @Published var textFieldModel = CustomTextFieldViewModel()


struct ContentView: View 
    @ObservedObject var viewModel = ContentViewModel()
    var body: some View 
        VStack 
            CustomTextField(viewModel: $viewModel.textFieldModel)
            Text("\($viewModel.textFieldModel.text.wrappedValue)") //<< wrappedValue
        
    

class CustomTextFieldViewModel: ObservableObject 
    @Published var text: String = "abc"


struct CustomTextField: View 
    @Binding var viewModel: CustomTextFieldViewModel //<< @Binding

    var body: some View 
        ZStack 
            Color.red
                .frame(height: 50)
            TextField("Enter text...", text: $viewModel.text)
        
    

【讨论】:

以上是关于在 SwiftUI MVVM 中的子视图和父视图之间共享值的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI MVVM:父视图更新时重新初始化子视图模型

SwiftUI 和 MVVM - 模型和视图模型之间的通信

如何在 SwiftUI 中实现 MVVM 模式?视图不会重新渲染

SwiftUI中sheet弹出嵌在NavigationView中的子视图无法用presentationMode关闭(dismiss)弹出视图的解决

SwiftUI ScrollView:查找当前在屏幕中心可见的子视图。子视图在 ScrollView 中的位置。偏好键。滚动视图代理

SwiftUI - MVVM之ViewModel