OutlineGroup is a view used to display hierarchical data in an expandable and collapsible list format. It’s useful for organizing data with multiple levels, like file systems, categories with subcategories, or other nested structures. OutlineGroup works by expanding each level to reveal its child elements, making it a great choice for displaying tree structures.
Basic Structure of OutlineGroup
To create an OutlineGroup, you need:
- A hierarchical data structure (often a custom
structorclass). - A way to identify children for each item in the hierarchy.
OutlineGroup(data, children: \.children) { item in
Text(item.name)
}
- data: The root data, typically an array representing the top level.
- children: The key path to the children of each item.
- content: Defines the view for each item.
Example with a Simple Data Model
Let’s define a simple hierarchical model with a name and children property.
import SwiftUI
struct Item: Identifiable {
let id = UUID()
let name: String
var children: [Item]? // Optional to allow leaf nodes with no children
}
struct ContentView: View {
let data: [Item] = [
Item(name: "Fruit", children: [
Item(name: "Apple"),
Item(name: "Banana"),
Item(name: "Cherry")
]),
Item(name: "Vegetables", children: [
Item(name: "Carrot"),
Item(name: "Lettuce")
])
]
var body: some View {
OutlineGroup(data, children: \.children) { item in
Text(item.name)
.padding(.leading, CGFloat(itemDepth(item: item)) * 10)
}
}
// Helper function to calculate depth for indentation
func itemDepth(item: Item) -> Int {
var depth = 0
var currentItem = item
while let parent = parentOf(item: currentItem) {
depth += 1
currentItem = parent
}
return depth
}
// Function to get the parent of an item (optional implementation depending on use case)
func parentOf(item: Item) -> Item? {
// Logic to find the parent, if necessary for custom indentation
return nil
}
}
Explanation
- Data Model: The
Itemstruct is the model for each entry in the outline, with anid,name, and optionalchildren. - OutlineGroup: Displays the data hierarchy. Each child item is indented using a
paddingbased on its depth. - Depth Calculation:
itemDepth(item:)calculates how deep each item is to determine how much it should be indented (optional).
Expanding and Collapsing
OutlineGroup automatically handles expanding and collapsing items based on whether they have children. For example:
- If an
Itemhaschildren, it appears as a collapsible row. - If it doesn’t have
children, it’s a leaf node and appears without expansion.
Adding Icons or Custom Views
To enhance each row in OutlineGroup, you can add icons or any custom views, making it resemble a file explorer with folders and files.
OutlineGroup(data, children: \.children) { item in
HStack {
Image(systemName: item.children == nil ? "leaf" : "folder")
Text(item.name)
}
}
This modification displays a “folder” icon for items with children and a “leaf” icon for items without children.
Nested Data with More Complex Hierarchies
When dealing with multiple nested levels, OutlineGroup automatically handles expanding the appropriate levels of the hierarchy.
For instance, given this nested data:
let data: [Item] = [
Item(name: "Animals", children: [
Item(name: "Mammals", children: [
Item(name: "Dogs"),
Item(name: "Cats"),
]),
Item(name: "Birds", children: [
Item(name: "Parrots"),
Item(name: "Sparrows")
])
])
]
Using OutlineGroup(data, children: \.children), each level expands as needed, revealing animals, then categories (e.g., “Mammals”), and specific items like “Dogs” and “Cats.”
OutlineGroup is a powerful SwiftUI component for hierarchical data. It:
- Automatically handles hierarchical layouts: Expands/collapses based on data structure.
- Customizable: Supports indentation, icons, and custom views.
- Ideal for tree structures: File systems, category trees, etc.