SwiftUI中的计算(NSObject)属性不会更新视图

thi*_*oxe 2 core-data swift computed-properties swiftui combine

因此,我想Text根据我的CoreData模型的内容来更改其内容。为此,我在Xcode beta 4中使用了一个计算属性,但是它似乎不再起作用。这是一个错误,还是我看不到其他问题?

我确切的问题是,self.objectWillChange.send()在我的商店中调用时,我的视图(和计算的属性)似乎没有更新。

我还试图将我的var“导出”到商店中,然后从那里得到它,结果相同。


编辑: 我只是对另一个类尝试了相同的方法,objectWillChange.send()但它仅与@Published但不一起工作,但是如果从NSObject继承的类则停止工作...


我才发现:

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()
    }
}


Run Code Online (Sandbox Code Playgroud)

那是我的问题的非常简化的版本,我知道我的DataModel可以工作,因为值会更改并被self.objectWillChange.send()调用,但是由于某些原因我的View并未更新。

mat*_*att 6

我看不到NSObject是问题的根源。问题似乎是您尚未实施objectWillChange。编译器将使您摆脱困境,但结果是您objectWillChange什么都不做。

这是一个简单的示例,该示例演示如何使用具有绑定功能的计算属性来配置ObservableObject(即NSObject):

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

通过单击按钮和开关,您可以看到所有内容均处于活动状态并对视图中的绑定做出了响应。