morzelek
morzelek

Reputation: 67

Embedded @Binding does not changing a value

Following this cheat sheet I'm trying to figure out data flow in SwiftUI. So:

Use @Binding when your view needs to mutate a property owned by an ancestor view, or owned by an observable object that an ancestor has a reference to.

And that is exactly what I need so my embedded model is:

class SimpleModel: Identifiable, ObservableObject {
    @Published var values: [String] = []

    init(values: [String] = []) {
        self.values = values
    }
}

and my View has two fields:

struct SimpleModelView: View {
    @Binding var model: SimpleModel
    @Binding var strings: [String]

    var body: some View {
        VStack {
            HStack {
                Text(self.strings[0])
                TextField("name", text: self.$strings[0])
            }
            HStack {
                Text(self.model.values[0])
                EmbeddedView(strings: self.$model.values)
            }
        }
    }
}

struct EmbeddedView: View {
    @Binding var strings: [String]

    var body: some View {
        VStack {
            TextField("name", text: self.$strings[0])
        }
    }
}

So I expect the view to change Text when change in input field will occur. And it's working for [String] but does not work for embedded @Binding object:

enter image description here

Why it's behaving differently?

Upvotes: 4

Views: 211

Answers (2)

Samuel-IH
Samuel-IH

Reputation: 813

In SimpleModelView, try changing:

@Binding var model: SimpleModel

to:

@ObservedObject var model: SimpleModel

@ObservedObjects provide binding values as well, and are required if you want state changes from classes conforming to ObservableObject

Upvotes: 1

Asperi
Asperi

Reputation: 258345

Make property published

class SimpleModel: Identifiable, ObservableObject {
    @Published var values: [String] = []

and model observed

struct SimpleModelView: View {
    @ObservedObject var model: SimpleModel

Note: this in that direction - if you introduced ObservableObject then corresponding view should have ObservedObject wrapper to observe changes of that observable object's published properties.

Upvotes: 2

Related Questions