I use disclousreGroup as recursion, but the view update doesn't work properly. Is there any way?

112 Views Asked by At

enter image description here

If you change the data after collapse, the View is reused and drawn strangely.

Reusing the View in swiftUI seems to produce these results.

Can I control the reuse of Views? Or is there another way?

Is it related to id?

Below is the code:

import SwiftUI

@main
struct TestApp: App {
    var item: Item = dummyItems
    var item2: Item = dummyItems2

    @State var isChange: Bool = true
    
    var body: some Scene {
        WindowGroup {
            VStack {
                List {
                    if isChange {
                        ContentView(item: item)
                    } else {
                        ContentView(item: item2)

                    }
                }
                Button("change") {
                    isChange.toggle()
                }
            }
        }
    }
}

import SwiftUI

struct ContentView: View {
    let item: Item
    
    init(item: Item) {
        self.item = item
    }
    
    var body: some View {
        ForEach(item.children) { item in
            if item.children.isEmpty {
                Text("\(item.title)")
            } else {
                DisclosureGroup(
                    isExpanded: item.$isExpanded,
                    content: {
                        ContentView(item: item)
                    },
                    label: { Text("\(item.title)") }
                )
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    
    static var previews: some View {
        let item: Item = dummyItems
        ContentView(item: item)
    }
}

struct Item: Identifiable {
    var id: UUID = UUID()
    
    @Binding var isExpanded: Bool
    var title: String = "title"
    var children: [Item] = []
    
    init(title: String,
         children: [Item]) {
        self.title = title
        self.children = children
        self._isExpanded = .constant(true)
    }
}

let dummyItems2 = Item(title: "root",
                      children: [
                        Item(title: "1",
                             children: [
                                Item(title: "1-1",
                                     children: [
                                        Item(title: "1-1-1",
                                             children: [])]
                                ),
                                Item(title: "1-2",
                                     children: [
                                        Item(title: "1-2-1",
                                             children: []),
                                        Item(title: "1-2-2",
                                             children: [])]
                                )
                             ]),
                        Item(title: "2",
                             children: [
                                Item(title: "2-1",
                                     children: [
                                        Item(title: "2-1-1",
                                             children: [])]
                                ),
                                Item(title: "2-2",
                                     children: [
                                        Item(title: "2-2-1",
                                             children: [])]
                                ),
                                Item(title: "2-3",
                                     children: [
                                        Item(title: "2-3-1",
                                             children: [])]
                                ),
                             ]),
                        Item(title: "3",
                             children: [
                                Item(title: "3-1",
                                     children: [
                                        Item(title: "3-1-1",
                                             children: []),
                                        Item(title: "3-1-2",
                                             children: []),
                                        Item(title: "3-1-3",
                                             children: [])]
                                ),
                                Item(title: "3-2",
                                     children: [
                                        Item(title: "3-1-1",
                                             children: [])]
                                ),
                                Item(title: "3-3",
                                     children: [
                                        Item(title: "3-1-1",
                                             children: [])]
                                )
                             ])
                        
                      ])



let dummyItems = Item(title: "root",
                      children: [
                        Item(title: "1",
                             children: [
                                Item(title: "1-1",
                                     children: [
                                        Item(title: "1-1-1",
                                             children: [])]
                                ),
                                Item(title: "1-2",
                                     children: [
                                        Item(title: "1-2-1",
                                             children: []),
                                        Item(title: "1-2-2",
                                             children: [])]
                                )
                             ]),
                        Item(title: "2",
                             children: [
                                Item(title: "2-1",
                                     children: [
                                        Item(title: "2-1-1",
                                             children: [])]
                                ),
                             ]),
                        Item(title: "3",
                             children: [
                                Item(title: "3-1",
                                     children: [
                                        Item(title: "3-1-1",
                                             children: []),
                                        Item(title: "3-1-2",
                                             children: []),
                                        Item(title: "3-1-3",
                                             children: [])]
                                ),
                                Item(title: "3-2",
                                     children: [
                                        Item(title: "3-1-1",
                                             children: [])]
                                ),
                                Item(title: "3-3",
                                     children: [
                                        Item(title: "3-1-1",
                                             children: [])]
                                )
                             ])
                        
                      ])
1

There are 1 best solutions below

1
Asperi On BEST ANSWER

Try the following

List {
    if isChange {
        ContentView(item: item)
    } else {
        ContentView(item: item2)

    }
}
.id(isChange)    // << here !!