So, I want to have a Text
that changes its content based on the contents of my CoreData Model. To do that I used a computed property in Xcode beta 4 but it doesn't seem to work anymore. Either that's a bug or there is some other issue I don't see?
The problem I have exactly is that my View (and the computed property) don't seem to get updated when self.objectWillChange.send()
is called in my store.
I also tried to 'export' my var into the store and get it from there, with the same result...
EDIT:
I just tried the same with another class and it didn't work with just objectWillChange.send()
but only with @Published
however, even that stopped working if the class inherited from NSObject...
I just found out: with
struct Today: View {
@EnvironmentObject var myStore: DateStore
var hasPlans: Bool {
guard let plans = myStore.getPlans() else { return false }
return plans.isEmpty
}
var body: some View{
VStack{
Text(hasPlans ? "I have plans":"I have time today")
Button(action: {
self.myStore.addPlans(for: Date())
}) {
Text("I have plans")
}
}
}
class DateStore: NSObject, ObservableObject, NSFetchedResultsControllerDelegate {
private var fetchedResultsController: NSFetchedResultsController<DateStore>
//...
public func addPlans(for date: Date){
//{...}
if let day = self.dates.first(where: { $0.date == date}){
day.plans += 1
saveChanges()
}else{
self.create(date: dayDate)
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.objectWillChange.send()
}
}
That's a very simplified version of my problem and I know that my DataModel works because the values change and self.objectWillChange.send()
is called, but my View isn't updated for some reason....
I don't see that NSObject is the source of the problem. The problem seems to be that you haven't implemented objectWillChange
. The compiler will let you get away with that, but the result is that your objectWillChange
does nothing.
Here's a simple example that shows how to configure an ObservableObject (that is an NSObject) with a computed property whose binding works:
class Thing : NSObject, ObservableObject {
let objectWillChange = ObservableObjectPublisher()
var computedProperty : Bool = true {
willSet {
self.objectWillChange.send()
}
}
}
struct ContentView: View {
@EnvironmentObject var thing : Thing
var body: some View {
VStack {
Button(self.thing.computedProperty ? "Hello" : "Goodbye") {
self.thing.computedProperty.toggle()
}
Toggle.init("", isOn: self.$thing.computedProperty).frame(width:0)
}
}
}
You can see by tapping the button and the switch that everything is live and responsive to the binding within the view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With