Everyone knows that since SwiftUI 2.0, List has supported the hierarchical display of recursive data.
My recursive data structure Tree is defined as follows:
class Tree<Value: Hashable>: Hashable {
static func == (lhs: Tree<Value>, rhs: Tree<Value>) -> Bool {
lhs.value == rhs.value
}
func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
let value: Value
var children: [Tree]? = nil
init(value: Value, children: [Tree]? = nil){
self.value = value
self.children = children
}
}
My Model is defined as follows:
class Model: ObservableObject {
@Published var trees = [Tree<String>]()
}
And finally my TreeView definition:
struct TreeView: View {
@StateObject var model = Model()
var body: some View {
VStack {
HStack {
Spacer()
Button(" "){
let new = Tree(value: String(UUID().uuidString.prefix(16)))
// List can be refreshed in time
model.trees.append(new)
}
}
.padding()
Text("Tree")
.font(.title)
Spacer()
List {
ForEach(model.trees, id: \.value){ section in
Section(header: HStack {
Text("\(section.value)")
Spacer()
Button(" "){
let new = Tree(value: String(UUID().uuidString.prefix(8)))
var new_children: [Tree<String>]
if let children = section.children {
new_children = children
new_children.append(new)
}else{
new_children = [new]
}
// List can't be refreshed in time
section.children = new_children
}
.buttonStyle(BorderlessButtonStyle())
}){
OutlineGroup(section.children ?? [], id: \.value, children: \.children){tree in
HStack {
Text(tree.value)
Spacer()
Button(" "){
let new = Tree(value: String(UUID().uuidString.prefix(8)))
var new_children: [Tree<String>]
if let children = tree.children {
new_children = children
new_children.append(new)
}else{
new_children = [new]
}
// List can't be refreshed in time
tree.children = new_children
}
.buttonStyle(BorderlessButtonStyle())
}
}
}
}
}
.listStyle(SidebarListStyle())
}
}
}
struct ProductListView_Previews: PreviewProvider {
static var previews: some View {
TreeView()
}
}
When I add a new Tree to the model.trees array, the List can be refreshed in time, but when I add a new Tree to an element in the trees array (eg: model.trees[0]), the List cannot be refreshed.
How can I refresh the list in time when adding sub-Trees? Thanks!
CodePudding user response:
as the first command of each " " Button insert:
model.objectWillChange.send()
- then it works.