Post

Replies

Boosts

Views

Activity

SwiftUI: Grandparent View Not Updating on Model Change in SwiftData
I'm working on a SwiftUI app using SwiftData for state management. I've encountered an issue with view updates when mutating a model. Here's a minimal example to illustrate the problem: import SwiftUI import SwiftData // MARK: - Models @Model class A { @Relationship var bs: [B] = [B]() init(bs: [B]) { self.bs = bs } } @Model class B { @Relationship var cs: [C] = [C]() init(cs: [C]) { self.cs = cs } } @Model class C { var done: Bool init(done: Bool) { self.done = done } } // MARK: - Views struct CView: View { var c: C var body: some View { @Bindable var c = c HStack { Toggle(isOn: $c.done, label: { Text("Done") }) } } } struct BView: View { var b: B var body: some View { List(b.cs) { c in CView(c: c) } } } struct AView: View { var a: A var body: some View { List(a.bs) { b in NavigationLink { BView(b: b) } label: { Text("B \(b.cs.allSatisfy({ $0.done }).description)") } } } } struct ContentView: View { @Query private var aList: [A] var body: some View { NavigationStack { List(aList) { a in NavigationLink { AView(a: a) } label: { Text("A \(a.bs.allSatisfy({ $0.cs.allSatisfy({ $0.done }) }).description)") } } } } } @main struct Minimal: App { var body: some Scene { WindowGroup { ContentView() } } } #Preview { let config = ModelConfiguration(isStoredInMemoryOnly: true) let container = try! ModelContainer(for: A.self, configurations: config) var c = C(done: false) container.mainContext.insert(c) var b = B(cs: [c]) container.mainContext.insert(b) var a = A(bs: [b]) container.mainContext.insert(a) return ContentView() .modelContainer(container) } In this setup, I have a CView where I toggle the state of a model C. After toggling C and navigating back, the grandparent view AView does not reflect the updated state (it still shows false instead of true). However, if I navigate back to the root ContentView and then go to AView, the status is updated correctly. Why doesn't AView update immediately after mutating C in CView, but updates correctly when navigating back to the root ContentView? I expected the grandparent view to reflect the changes immediately as per SwiftData's observation mechanism.
1
1
637
Nov ’23