iOS SwiftUI:从父到子的 ObservableObject

And*_*tto 5 ios swift swiftui combine

问题:

传递视图模型并从子级修改它,不会刷新父级。

我想要的是:

每当我从子视图修改视图模型时,父视图也会刷新。

问题描述:

我正在寻找一种将 a 传递ViewModel ObservedObject给一些子视图的方法。

这是我的结构:

struct Parent: View {
    @ObservedObject viewModel: ViewModel

     var body: some View {
            NavigationView {
                Form {
                    ScrollView(showsIndicators: false) {
                         Section {
                            ChildViewOne(model: viewModel)
                        }
                        
                        Section {
                            ChildViewTwo(model: viewModel)
                        }
                        
                        Section {
                            ChildViewThree(model: viewModel)
                        }
                    }
                }
            }
        }
}

struct AnyChild: View {
    @ObservedObject viewModel: ViewModel

     var body: some View {
            // some stuff
        }
}
Run Code Online (Sandbox Code Playgroud)

这样,每当我从子视图修改视图模型时,子视图都会正确重建,但父视图不会,并且滚动视图不会正确调整大小。

我想将 viewModel 像 Binding 对象一样传递给孩子,这样父母也会刷新。

但我不知道该怎么做。有什么帮助吗?

解决方案:

Form当我删除一切正常时,我遇到了一个特定的问题。

@Alladinian所写的正确解决方案仍然是使用 @EnvironmentObject

All*_*ian 5

您可以使用@EnvironmentObject专为此设计的模型,而不是将相同的模型传递给每个子视图。

您基本上必须ObservableObject在您的父视图中注入类似这样的东西(通常在您的 appdelegate 中,在呈现父视图之前,或在您的预览设置中进行实时预览):

Parent().environmentObject(ViewModel())
Run Code Online (Sandbox Code Playgroud)

然后你可以在每个视图中自动获取一个引用,如下所示:

struct AnyChild: View {
    @EnvironmentObject var model: ViewModel
    //...
}
Run Code Online (Sandbox Code Playgroud)

并将其与您的绑定一起使用

这里简单介绍一下环境的使用

最后,关于为什么您的解决方案不起作用,您必须考虑一个单一的事实来源(您的父级中的可观察对象)和@Binding每个子视图最终会更改此对象的状态。我希望这是有道理的...

  • `@EnvironmentObject` 看起来像是一个美化的全局变量。我很惊讶对于更复杂的对象没有“@State”/“@Binding”类似物 (4认同)