SwiftUI - ObservableObject created multiple times

爷,独闯天下 提交于 2020-12-28 20:39:39

问题


I have created an ObservableObject in a View.

@ObservedObject var selectionModel = FilterSelectionModel()

I put a breakpoint inside the FilterSelectionModel's init function and it is called multiple times. Because this View is part of a NavigationLink, I understand that it gets created then and along with it, the selectionModel. When I navigate to the View, the selectionModel is created again.

In this same View I have a "sub View" where I pass the selectionModel as an EnvironmentObject so the sub-view can change it.

AddFilterScreen().environmentObject(self.selectionModel)

When the sub view is dismissed, the selectionModel is once more created and the changes made to it have disappeared.

Interesting Note: At the very top level is a NavigationView. IF I add

.navigationViewStyle(StackNavigationViewStyle())

to this NavigationView, my selectionModel's changes disappear. BUT if I do not add the navigationStyle, the selectionModel's changes made in the sub view remain!! (But I don't want a split nav view, I want a stacked nav view)

In both cases - with or without the navigationStyle, the selectionModel is created multiple times. I can't wrap my head around how any of this is supposed to work reliably.


回答1:


You can instantiate the observable object in the init method, in this way you will be able to hold its value or the value won't disappear.

Instantiate this way in the view file.

@ObservedObject var selectionModel : FilterSelectionModel

init() {
   selectionModel = FilterSelectionModel(value : "value to be saved from disappearing")
}

Instantiate this way in the viewModel file.

class FilterSelectionModel : ObservableObject {

  @Published var value : String

  init(value : String) {
     self.value = value
  }

}

This is a workaround that I found, but still, the init method is called multiple times and I didn't get any success with this issue.

In order to stop multiple initializing of the ViewModels as the view is declared in the Navigation View and SwiftUI uses struct which is a value type, so eventually these are initialized before the view is presented, therefore you can convert that view into a LazyView, so that it will only be initialized once the view is about to be presented or shown.

// Use this to delay instantiation when using `NavigationLink`, etc...
struct LazyView<Content: View>: View {
    var content: () -> Content
    var body: some View {
       self.content()
    }
}

You can call it like this...

 NavigationLink(destination: LazyView { ViewTobePresented() }) 


来源:https://stackoverflow.com/questions/59533407/swiftui-observableobject-created-multiple-times

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!