问题
I have a SwiftUI view that takes in an EnvironmentObject called appModel. It then reads the value appModel.submodel.count in its body method. I expect this to bind my view to the property count on submodel so that it re-renders when the property updates, but this does not seem to happen.
Is this a bug? And if not, what is the idiomatic way to have views bind to nested properties of environment objects in SwiftUI?
Specifically, my model looks like this...
class Submodel: ObservableObject {
@Published var count = 0
}
class AppModel: ObservableObject {
@Published var submodel: Submodel = Submodel()
}
And my view looks like this...
struct ContentView: View {
@EnvironmentObject var appModel: AppModel
var body: some View {
Text("Count: \(appModel.submodel.count)")
.onTapGesture {
self.appModel.submodel.count += 1
}
}
}
When I run the app and click on the label, the count property does increase but the label does not update.
I can fix this by passing in appModel.submodel as a property to ContentView, but I'd like to avoid doing so if possible.
回答1:
Nested models does not work yet in SwiftUI, but you could do something like this
class Submodel: ObservableObject {
@Published var count = 0
}
class AppModel: ObservableObject {
@Published var submodel: Submodel = Submodel()
var anyCancellable: AnyCancellable? = nil
init() {
anyCancellable = submodel.objectWillChange.sink { (_) in
self.objectWillChange.send()
}
}
}
Basically your AppModel catches the event from Submodel and send it further to the View
Edit:
If you do not need SubModel to be class, then you could try something like this either:
struct Submodel{
var count = 0
}
class AppModel: ObservableObject {
@Published var submodel: Submodel = Submodel()
}
回答2:
It looks like bug. When I update the xcode to the latest version, it work correctly when binding to nested ObservableObjects
来源:https://stackoverflow.com/questions/58406287/how-to-tell-swiftui-views-to-bind-to-nested-observableobjects