Reputation: 67
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:
Why it's behaving differently?
Upvotes: 4
Views: 211
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
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