I am trying to figure how to have a SwiftUI view properly react to the changes made to an NSManagedObject property.
Example:
class MyViewModel: ObservableObject {
@Published var car:Car // <-- NSManagedObject
@Published var sold:Bool = false // <-- I don't want to do this, I want to simply observe the sold property on car and not have to implement this sink logic below
var subs = [AnyCancellable]()
init(car:Car) {
self.car = car
self.sold = car.sold
self.car.publisher(for: \.sold)
.removeDuplicates()
.receive(on: RunLoop.main)
.sink { [weak self] sold in
self?.sold = sold
}
.store(in: &subs)
}
}
As an example, I have a Toggle that lets me set the sold
property on the Car entity.
Toggle(isOn: Binding<Bool>(get: { model.car.sold }, set: { model.car.sold = $0 } )) {
if model.car.sold {
Text("ON")
} else {
Text("OFF")
}
}
Toggling the control does set the sold
property on the car instance, but, the Toggle label:
if model.car.sold {
Text("ON")
} else {
Text("OFF")
}
does not update accordingly.
So, if I change the car entity as a whole, things update, if I change a property of the entity the view does not update. So then I implemented the sink
logic to then set a published sold
property on the model. So the sold
property on the car is set by the toggle, the sink kicks in and sets the model.sold, and then the Toggle label Text does update.
How can I do away with the additional @Published var sold:Bool = false
in the model and simply cause the Toggle label to react to the actual car.sold
property?
CodePudding user response:
Observe Car directly, it confirms to ObservableObject, so instead of view model pass in view it like
struct CarView: View {
@ObservedObject var car: Car