在 NSManagedObject 编辑上更新 SwiftUI 视图
Posted
技术标签:
【中文标题】在 NSManagedObject 编辑上更新 SwiftUI 视图【英文标题】:Update SwiftUI View on NSManagedObject edit 【发布时间】: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()
强制,但不起作用。我在这个问题上挣扎了很多,我很困惑我错过了什么
【参考方案1】:
在花了很长时间试图理解这种行为并使用我对 SwiftUI、CoreData 和 Combine 的所有知识之后,我终于通过将 id
添加到我的 ForEach
来“修复”,如下所示:
ForEach(training.exerciceHistories.array as! [ExerciceHistory], id: \.self)
exerciceHistory in
ExerciceHistoryRow(exerciceHistory: exerciceHistory)
.padding(.bottom, 10)
.id(UUID())
【讨论】:
以上是关于在 NSManagedObject 编辑上更新 SwiftUI 视图的主要内容,如果未能解决你的问题,请参考以下文章
在具有 VIPER 架构的应用程序上更新 NSManagedObject
iOS 8 Swift:使用 segue 编辑 NSManagedObject:声明类型时出错
当模型编辑器中的模型更改时重新创建 NSManagedObject 子类
如何使用更新的数据刷新 NSManagedObject - Core Data