I have an ObservableObject class, Model0
which has a Published
object nested
. The nested
object represents a recursive tree structure. I want to be able to update the tree structure and have the UI update appropriately. However, in the below code, when I update a child of the nested
object, the UI is not updated, I assume because the reference to nested
is not changed. How can I get the UI to update whenever I change any of the nested
objects in the tree structure?
class Nested: Identifiable {
var id: UUID = UUID()
var name: String
var children:[Nested]
init(name: String, children:[Nested]) {
self.children = children
self.name = name
}
}
class Model0 : ObservableObject {
@Published var nested: Nested
init(nested: Nested) {
self.nested = nested
}
func update() {
nested.children[0] = Nested(name:"New", children: [])
}
}
struct NestedView: View {
var nested: Nested
var body: some View {
VStack {
Text(nested.name)
ForEach(nested.children) { c in
NestedView(nested: c)
}
}
}
}
struct Test: View {
@ObservedObject var model: Model0 = Model0(nested: Nested(name: "Parent" ,children: [Nested(name: "Child", children: [])]))
var body: some View {
VStack {
Button(action: {
self.model.update()
}) {
Text("Update")
}
NestedView(nested: model.nested)
}
}
}
If you decided to make reference-type model, then you need to make all of them observable, so each level could update corresponding view. And, of course, have separated view for each level model.
Taking above into account, here is a solution. Tested with Xcode 12 / iOS 14.
Modified part only:
class Nested: ObservableObject, Identifiable {
var id: UUID = UUID()
@Published var name: String
@Published var children:[Nested]
init(name: String, children:[Nested]) {
self.children = children
self.name = name
}
}
struct NestedView: View {
@ObservedObject var nested: Nested
var body: some View {
VStack {
Text(nested.name)
ForEach(nested.children) { c in
NestedView(nested: c)
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With