Home > Net >  SwiftUI 2.0 How to refresh List in time when add new subitems?
SwiftUI 2.0 How to refresh List in time when add new subitems?

Time:02-17

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.

  • Related