iOS Development

ios – SwiftUI: Grandparent View Not Updating on Mannequin Change in SwiftData

I am engaged on a SwiftUI app utilizing SwiftData for state administration. I’ve encountered a problem with view updates when mutating a mannequin. This is a minimal instance for example the issue:

import SwiftUI
import SwiftData

// MARK: - Fashions

@Mannequin
class A {
  @Relationship var bs: [B] = [B]()
  
  init(bs: [B]) {
    self.bs = bs
  }
}

@Mannequin
class B {
  @Relationship var cs: [C] = [C]()
  
  init(cs: [C]) {
    self.cs = cs
  }
}

@Mannequin
class C {
  var carried out: Bool
  
  init(carried out: Bool) {
    self.carried out = carried out
  }
}

// MARK: - Views

struct CView: View {
  var c: C
  
  var physique: some View {
    @Bindable var c = c
    HStack {
      Toggle(isOn: $c.carried out, label: {
        Textual content("Performed")
      })
    }
  }
}

struct BView: View {
  var b: B
  
  var physique: some View {
    Checklist(b.cs) { c in
      CView(c: c)
    }
  }
}

struct AView: View {
  var a: A
  
  var physique: some View {
    Checklist(a.bs) { b in
      NavigationLink {
          BView(b: b)
      } label: {
        Textual content("B (b.cs.allSatisfy({ $0.carried out }).description)")
      }
    }
  }
}

struct ContentView: View {
  @Question non-public var aList: [A]
  
  var physique: some View {
    NavigationStack {
      Checklist(aList) { a in
        NavigationLink {
          AView(a: a)
        } label: {
          Textual content("A (a.bs.allSatisfy({ $0.cs.allSatisfy({ $0.carried out }) }).description)")
        }
      }
    }
  }
}

@major
struct Minimal: App {
  var physique: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}

#Preview {
  let config = ModelConfiguration(isStoredInMemoryOnly: true)
  let container = strive! ModelContainer(for: A.self, configurations: config)
  
  var c = C(carried out: 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)
}

On this setup, I’ve a CView the place I toggle the state of a mannequin C. After toggling C and navigating again, the grandparent view AView doesn’t replicate the up to date state (it nonetheless reveals false as an alternative of true). Nevertheless, if I navigate again to the basis ContentView after which go to AView, the standing is up to date accurately.

Why does not AView replace instantly after mutating C in CView, however updates accurately when navigating again to the basis ContentView? I anticipated the grandparent view to replicate the adjustments instantly as per SwiftData’s commentary mechanism.

Credit: www.ismmailgsm.com

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button