Update State-variable Whenever CoreData is Updated in SwiftUI

淺唱寂寞╮ 提交于 2021-02-08 11:18:19

问题


After updating some data from CoreData, I also want to update a State-variable to the number of returned results.

When CoreData is changed, the Stepper should always be set to the number of returned results. However, onAppear fires also when I use the Stepper. How can I check in onAppear whether CoreData was changed or the Stepper was used? Is that even possible?

import SwiftUI

struct ContentView: View {
@State var numberOfResults = 0

@FetchRequest(entity: YourModel.entity(), sortDescriptors: [], predicate:NSPredicate(format: "isSelected == %@", NSNumber(booleanLiteral: true))) var objects: FetchedResults<YourModel>

var body: some View{
    return VStack{

        Stepper("text", value: $numberOfResults, in: 0...objects.wrappedValue.count, step:5)
            .onReceive(objects.publisher, perform: {_ in
                self.numberOfResults = self.objects.count
                print("onReceive")
            })
        }
    }
}

回答1:


If you use @FetchRequest and onReceive numberOfResults will be updated when the publisher sends a message

import SwiftUI

struct DidSetCoreData: View {
    @State var numberOfResults = 0
    @State var initSetup1: Bool = true
    @State var initSetup2: Bool = true
    @State var adjustedCount = 0
    @FetchRequest(entity: YourModel.entity(), sortDescriptors: [], predicate:NSPredicate(format: "isSelected == %@", NSNumber(booleanLiteral: true))) var objects: FetchedResults<YourModel>

    var body: some View{
    return VStack{
            Text("Total Count= \(objects.count)")
            Text("Adjusted Total = \($adjustedCount.wrappedValue)")
            //You need the separate adjusted count variable to save the changes

            //Option 1 Stepper - Keeps the max step flexible, eliminates the need for the numberOfResults var
            Stepper("AdjTotal - FlexibleMax", value: $adjustedCount, in: 0...objects.count, step:5)
            .onReceive(objects.publisher.count(), perform: {count in
                //onReceive will be called everytime there is a change to objects.count or body refresh
                print("onReceive - Option 1")
                if self.initSetup1{
                    //The variable will only be setup once
                    self.adjustedCount = count
                    self.initSetup1 = false
                    print("initSetupComplete - Option 1")
                }
            })

            //Option 2 Stepper
            Stepper("AdjTotal - initMax", value: $adjustedCount, in: 0...$numberOfResults.wrappedValue, step:5)

            .onReceive(objects.publisher.count(), perform: {count in
                //onReceive will be called everytime there is a change to objects.count or body refresh
                print("onReceive - Option 2")
                if self.initSetup2{
                    //The variables will only be setup once
                    self.numberOfResults = count //Limits the max step to only the original count
                    self.adjustedCount = self.numberOfResults
                    self.initSetup2 = false
                    print("initSetupComplete - Option 2")
                }
            })
            //Option 3 Stepper - Limits the StepperMax to the Stepper value
            Stepper("AdjTotal - ValueMax", value: $numberOfResults, in: 0...$numberOfResults.wrappedValue, step:5)
            .onReceive(objects.publisher.count(), perform: {count in
                //onReceive will be called everytime there is a change to objects.count or body refresh
                print("onReceive - Option 3")
                if self.initSetup3{
                    //The variable will only be setup once
                    self.numberOfResults = count
                    self.initSetup3 = false
                    print("initSetupComplete - Option 3")
                }
           })
        }
    }
}



回答2:


You don't need @State var numberOfResults. You can use just objects.count in a Text(). The wrapper @FetchRequest do all the work for you. Whenever you add a YourModel entity object into ManagedObjectContext, it will trigger FetchRequest to refresh and give you actual result. @FetchRequest is already do things like @State



来源:https://stackoverflow.com/questions/59954342/update-state-variable-whenever-coredata-is-updated-in-swiftui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!