Question
Answer and Explanation
Creating a SwiftUI List with expandable child views in the second layer involves using a combination of `List`, `DisclosureGroup`, and state management. Here's a breakdown of how you can achieve this:
1. Data Structure:
- First, define a data structure that represents your hierarchical data. This structure should include a way to represent parent-child relationships and whether a group is expanded or not. For example:
struct Item: Identifiable {
let id = UUID()
let name: String
var children: [Item]?
}
2. State Management:
- Use `@State` variables to manage the expansion state of each `DisclosureGroup`. You can use a dictionary to store the expansion state for each item's ID.
3. SwiftUI List and DisclosureGroup:
- Use a `List` to display the top-level items. Inside the `List`, use `DisclosureGroup` to create expandable sections for items with children. Here's an example:
struct ContentView: View {
@State private var items: [Item] = [
Item(name: "Parent 1", children: [
Item(name: "Child 1.1"),
Item(name: "Child 1.2")
]),
Item(name: "Parent 2", children: [
Item(name: "Child 2.1"),
Item(name: "Child 2.2", children: [
Item(name: "Grandchild 2.2.1")
])
])
]
@State private var expandedItems: [UUID: Bool] = [:]
var body: some View {
List {
ForEach(items) { item in
DisclosureGroup(isExpanded: Binding(get: { expandedItems[item.id, default: false] }, set: { expandedItems[item.id] = $0 })) {
Text(item.name)
} content: {
if let children = item.children {
ForEach(children) { child in
if let grandChildren = child.children {
DisclosureGroup(isExpanded: Binding(get: { expandedItems[child.id, default: false] }, set: { expandedItems[child.id] = $0 })) {
Text(child.name)
} content: {
ForEach(grandChildren) { grandChild in
Text(grandChild.name).padding(.leading, 20)
}
}
} else {
Text(child.name).padding(.leading, 20)
}
}
}
}
}
}
}
}
4. Explanation:
- The `Item` struct defines the structure of your data, including an optional array of child items.
- The `expandedItems` dictionary keeps track of which `DisclosureGroup` is expanded using the item's ID as the key.
- The `List` iterates through the top-level items. For each item, a `DisclosureGroup` is created. The `isExpanded` binding is used to control the expansion state of the group.
- If an item has children, another `ForEach` loop is used to display them. The children are indented using `padding(.leading, 20)` for visual hierarchy.
- If a child has grand children, another `DisclosureGroup` is created to display them.
5. Customization:
- You can customize the appearance of the list and the `DisclosureGroup` using SwiftUI modifiers.
By following these steps, you can create a SwiftUI List with expandable child views in the second layer, allowing users to navigate hierarchical data effectively.