Reputation: 412
I'm trying to update a SwiftUI (sub) view on property update of NSManagedObject (Training
).
The property is an NSOrderedSet (exerciceHistories
).
Piece of Training
class :
extension Training {
...
@NSManaged public var date: Date
@NSManaged public var exerciceHistories: NSOrderedSet
}
The main view is TrainingDetail
, displaying detail of 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()
}}
....
}
...
}
}
Interesting part of TrainingDetailExercices
, where editing sheet is opened :
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 that is the sheet displayed, where we can edit one element of training property NSOrderedSet (exerciceHistories
):
struct TrainingAddExercice: View {
...
@ObservedObject private var trainingAddExerciceViewModel: TrainingAddExerciceViewModel
@ObservedObject var training: Training
...
}
The function that save and close sheet in 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(...)
}
}
One thing I don't understand is that when I'm adding/deleting one ExerciceHistory to/of training.exerciceHistories, view updates but not when I'm editing one even so I'm trying to force by creating new OrderedSet.
Object is well update in CoreData.
Upvotes: 0
Views: 170
Reputation: 412
After spending a long time trying to understand the behavior and using all my knowledge of SwiftUI, CoreData and Combine, I finally "fix" by adding id
to my ForEach
like this :
ForEach(training.exerciceHistories.array as! [ExerciceHistory], id: \.self) {
exerciceHistory in
ExerciceHistoryRow(exerciceHistory: exerciceHistory)
.padding(.bottom, 10)
}.id(UUID())
Upvotes: 0