我在视图中创建了一个ObservableObject。
@ObservedObject var selectionModel = FilterSelectionModel()我在FilterSelectionModel的init函数中放置了一个断点,它被多次调用。因为这个视图是NavigationLink的一部分,所以我知道它是和它一起创建的,即selectionModel。当我导航到视图时,会再次创建selectionModel。
在同一视图中,我有一个“子视图”,其中我将selectionModel作为一个EnvironmentObject传递,这样子视图就可以更改它。
AddFilterScreen().environmentObject(self.selectionModel)当子视图被取消时,将再次创建selectionModel,并且对其所做的更改已经消失。
有趣的注意:在最顶层是一个NavigationView。如果我加上
.navigationViewStyle(StackNavigationViewStyle())对于这个NavigationView,我的选择模型的更改消失了。但是如果我不添加navigationStyle,那么选择模型在子视图中所做的更改将保持不变!!(但我不想要一个分割的导航视图,我想要一个堆叠的导航视图)
在这两种情况下--不管有没有navigationStyle,selectionModel都是多次创建的。我不知道这其中的任何一个应该如何可靠地工作。
发布于 2021-03-07 18:48:12
最新的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)使用@StateObject对User对象进行注释,共享该对象的所有其他视图(NameCount)都在使用@ObservedObject。
通过这种方法,当您的父视图(ContentView)被重新创建时,User对象将不会被重新创建,它将持久化它的@State,而您的子视图--只是对同一个User对象的observing --不必关心它的重新创建。
发布于 2020-03-24 07:36:36
您可以在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使用的是值类型的结构,因此最终在视图出现之前对这些结构进行初始化,因此您可以将该视图转换为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() }) https://stackoverflow.com/questions/59533407
复制相似问题