Nitisha Sharma
Nitisha Sharma

Reputation: 303

NavigationModel with iOS17 Observation

I'm playing around with new @Observable and kind of stuck around how to make properties bindable if it's inside environment object.

So, in app i've setup navigation programmatically as apple suggests "Robust Navigation"

and NavigationModel is injected as environmentObject and property columnVisibility is a part of same model and passed as a binding property to NavigationSplitview With new Observation macro, seems like we can pass properties from environment object as binding.

final class NavigationModel: ObservableObject, Codable {
    @Published var selectedCategory: Category?
    @Published var recipePath: [Recipe]
    @Published var columnVisibility: NavigationSplitViewVisibility
    }

 NavigationSplitView(
        columnVisibility: $navigationModel.columnVisibility
    )

With Observation Macro

@Observable
final class NavigationModel {
 var columnVisibility: NavigationSplitViewVisibility = .automatic 
}

When trying to do the same, it fails enter image description here

enter image description here

Is there something i'm missing ?

One solution i can think of is move columnVisibility to some other class and make it Observable using macro or define property in same view.

Upvotes: 0

Views: 680

Answers (2)

Timothy Cleveland
Timothy Cleveland

Reputation: 1

You need to add a variable with the @Bindable property wrapper in the view's body linked to your model.

According to Apple:

You can use the Bindable property wrapper on properties and variables to an Observable object. This includes global variables, properties that exists outside of SwiftUI types, or even local variables. For example, you can create a @Bindable variable within a view’s body

So, your code would look like this:

struct HomePageView: View {
    @Environment(NavigationModel.self) var navigationModel

    var body: some View {
        @Bindable var navigationModelWithBinding = navigationModel
        NavigationSplitView(columnVisibility: $navigationModelWithBinding.columnVisibility)
        ...
    }
}

Upvotes: 0

malhal
malhal

Reputation: 30746

You're missing the conversion to @Bindable:

@Bindable var navigationModel = navigationModel
NavigationSplitView(columnVisibility: $navigationModel.columnVisibility)

You wouldn't have needed this if you used an @State struct instead of a class.

Upvotes: -1

Related Questions