Michał Ziobro
Michał Ziobro

Reputation: 11752

SwiftUI ObservableObject and @ObservedObject not keeping state

I have code like this:

struct MenuView : View {

    @Environment(\.verticalSizeClass) var sizeClass
    @EnvironmentObject var model : MenuModel

    @ObservedObject var items = MenuItems()

    var body: some View { 

    }

}

And I consider why ObservableObject is not keeping it state (there is no one instance of this object) but rather it is recreated (init() method is called) on each View redrawing while some other state changes. I think it is once per object.

But tapping the button causes View to be recreated and also this ObservedObject to be recreated. Should I create it not via property initialization but rather in parent and pass it to constructor?

How to correctly pass @ObservedObject to child view? I consider passing it to @Bindable property but it doesn't work.

I am changing via Button model.isMenuOpen @Published property

Upvotes: 1

Views: 1433

Answers (1)

samwize
samwize

Reputation: 27353

There is some "magic" by SwiftUI in restoring the state (be it @State or @ObservedObject) of a view. Those states are managed by SwiftUI, and they are restored before body is called.

Your child view can have an initialization, but note it has to be like this:

init(foo: Foo) {
    self._foo = ObservedObject(initialValue: foo)
}

You you might also want your view to extend Equatable, to help in the diff-ing.

I wrote more on the weird things about state here: https://samwize.com/2020/04/30/a-few-things-about-state/

Upvotes: 2

Related Questions