我已经在视图中创建了一个ObservableObject。
@ObservedObject var selectionModel = FilterSelectionModel()
我在FilterSelectionModel
的{{1}}函数中放置了一个断点,它被多次调用。因为此View是init
的一部分,所以我了解到它是在那时创建的,并且是selectionModel。当我导航到视图时,会再次创建selectionModel。
在同一视图中,我有一个“子视图”,在其中我将selectionModel传递为NavigationLink
,以便子视图可以更改它。
EnvironmentObject
关闭子视图后,将再次创建selectionModel,并且对其所做的更改也将消失。
有趣的注释:最顶层是AddFilterScreen().environmentObject(self.selectionModel)
。如果我添加
NavigationView
对此.navigationViewStyle(StackNavigationViewStyle())
而言,我的selectionModel的更改消失了。但是,如果我不添加NavigationView
,则在子视图中对selectionModel所做的更改仍然保留! (但是我不想要分割的导航视图,我想要一个堆叠的导航视图)
在两种情况下(无论是否带有navigationStyle
,都会多次创建selectionModel。我无法确定应该如何可靠地工作。
答案 0 :(得分:6)
您可以在init方法中实例化可观察对象,这样就可以保留其值,否则该值不会消失。
以这种方式在视图文件中实例化。
@ObservedObject var selectionModel : FilterSelectionModel
init() {
selectionModel = FilterSelectionModel(value : "value to be saved from disappearing")
}
以这种方式在viewModel文件中实例化。
class FilterSelectionModel : ObservableObject {
@Published var value : String
init(value : String) {
self.value = value
}
}
这是我发现的解决方法,但仍然多次调用init方法,但在此问题上我没有获得任何成功。
为了在视图在导航视图中声明时停止ViewModels的多次初始化,并且SwiftUI使用值类型的struct,因此最终在视图出现之前对其进行了初始化,因此您可以将该视图转换为LazyView,因此只有在视图将要显示或显示时才对其进行初始化。
// Use this to delay instantiation when using `NavigationLink`, etc...
struct LazyView<Content: View>: View {
var content: () -> Content
var body: some View {
self.content()
}
}
您可以这样称呼...
NavigationLink(destination: LazyView { ViewTobePresented() })
答案 1 :(得分:2)
最新的 SwiftUI 更新为这个问题带来了解决方案。 (iOS 14 以上)
@StateObject
是我们应该使用的而不是 @ObservedObject
,但仅限于创建该对象的地方,而不是我们传递相同对象的子视图中的任何地方。
例如-
class User: ObservableObject {
var name = "mohit"
}
struct ContentView: View {
@StateObject var user = User()
var body: some View {
VStack {
Text("name: \(user.name)")
NameCount(user: self.user)
}
}
}
struct NameCount: View {
@ObservedObject var user
var body: some View {
Text("count: \(user.name.count)")
}
}
在上面的示例中,只有负责创建该对象的视图 (ContentView) 使用 User
和所有其他视图 (NameCount ) 共享对象正在使用 @StateObject
。
通过这种方法,无论何时重新创建父视图,都不会重新创建 @ObservedObject
对象,并且它会持续存在,而您的子视图仅 User
到相同的 observing
对象不必关心它的重新创建。
希望这会有所帮助。快乐编码...