skip to Main Content

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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)
            ...
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search