【问题标题】:Update SwiftUI View on NSManagedObject edit在 NSManagedObject 编辑上更新 SwiftUI 视图
【发布时间】:2020-08-07 21:59:30
【问题描述】:

我正在尝试更新有关 NSManagedObject (Training) 的属性更新的 SwiftUI(子)视图。 该属性是一个 NSOrderedSet (exerciceHistories)。

Training 类的片段:

extension Training {

    ...

    @NSManaged public var date: Date
    @NSManaged public var exerciceHistories: NSOrderedSet
}

主视图是TrainingDetail,显示Training的详细信息:

struct TrainingDetail: View {
    @Environment(\.managedObjectContext) var managedObjectContext
    
    @ObservedObject var training: Training
    ...
    
    var body: some View {
        ZStack {
            ...
            ScrollView(.vertical, showsIndicators: false) {
                VStack(spacing: 0) {
                    ...
                    TrainingDetailAction(training: training, new: new) //-> View that creates sheet to edit one element of training property NSOrderedSet (`exerciceHistories`)
                    TrainingDetailExercices(training: training, editing: $new) //-> View displaying training property NSOrderedSet (`exerciceHistories`)
                        .padding()
                }}
                ....
            }
            ...
        }
    }

TrainingDetailExercices 的有趣部分,其中打开了编辑表:

struct TrainingDetailExercices: View {
    @Environment(\.managedObjectContext) var managedObjectContext
    
    @ObservedObject var training: Training

    var body: some View {

...

                     ForEach(training.exerciceHistories.array as! [ExerciceHistory], id: \.self) {
                    exerciceHistory in

                     ExerciceHistoryRow(exerciceHistory: exerciceHistory)
                            .padding(.bottom, 10)
                    }.sheet(isPresented: $showEditView, onDismiss: {
                    ...
                }, content: {
                TrainingAddExercice(training: self.training, ...)
                    .environment(\.managedObjectContext, self.managedObjectContext)
            })

TrainingAddExercice 是显示的工作表,我们可以在其中编辑训练属性 NSOrderedSet (exerciceHistories) 的一个元素:

struct TrainingAddExercice: View {
    ...
    @ObservedObject private var trainingAddExerciceViewModel: TrainingAddExerciceViewModel
    
    @ObservedObject var training: Training
    ...
    
}

TrainingAddExercice中保存和关闭表单的功能:

    private func trailingNavButtons() -> some View {
            HStack{
                ....
                
                Button(action: {
                    self.trainingAddExerciceViewModel.save(exerciceHistory: self.exerciceHistory, to: self.managedObjectContext, for: self.training)
    
    //here I'm trying to force update by creating a new NSMutableOrderedSet and assign it to training (because NSMutableOrderedSet is class, not struct) 

                    let newExercicesHistories = NSMutableOrderedSet(orderedSet: self.training.exerciceHistories)
                    self.training.exerciceHistories = newExercicesHistories
                    self.show = false
              
  }, label: {
                ...
            }).disabled(...)
        }
    }

我不明白的一件事是,当我向 training.exerciceHistories 添加/删除一个 ExerciceHistory 时,查看更新但在我编辑一个时却没有,所以我试图通过创建新的 OrderedSet 来强制.

对象在 CoreData 中得到很好的更新。

【问题讨论】:

  • 你可以使用self.training.objectWillChange.send()强制刷新 ObservableObjects
  • 已经尝试使用self.training.objectWillChange.send() 强制,但不起作用。我在这个问题上挣扎了很多,我很困惑我错过了什么

标签: swift core-data swiftui nsmanagedobject nsorderedset


【解决方案1】:

在花了很长时间试图理解这种行为并使用我对 SwiftUI、CoreData 和 Combine 的所有知识之后,我终于通过将 id 添加到我的 ForEach 来“修复”,如下所示:

ForEach(training.exerciceHistories.array as! [ExerciceHistory], id: \.self) {
exerciceHistory in
    ExerciceHistoryRow(exerciceHistory: exerciceHistory)
    .padding(.bottom, 10)
}.id(UUID())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    相关资源
    最近更新 更多