26
Apr
2021
File Tree with Expanding List in SwiftUI
Reading time: 2 min
This recipe shows how to create a simple file tree using SwiftUI expandable list. This feature is useful for representing any hierarchical data structure, allowing the user to expand and collapse branches to navigate the tree.
The end result looks like this:
This feature is only available starting iOS 14.
OK, to make this work, data for your List
must satisfy two conditions:
- It has to be
Identifiable
. - It has to be tree-structured, meaning that each item needs to have a field that is an optional array of the same type. This allows you to recursively build a tree of items and use
nil
to specify if an item is a branch or a leaf.
Here's a sample data structure that covers both points:
// Represents a simple file or a folder
struct File: Identifiable { // identifiable ✓
let id = UUID()
let name: String
var children: [File]? // optional array of type File ✓
var icon: String { // makes things prettier
if children == nil {
return "doc"
} else if children?.isEmpty == true {
return "folder"
} else {
return "folder.fill"
}
}
}
And here's some sample data:
let items = [
File(name: "Documents", children: [
File(name: "Work", children: [
File(name: "Revision 1.doc", children: nil),
File(name: "Revision 2.doc", children: nil),
]),
File(name: "Sheet 1.pdf", children: nil),
File(name: "Sheet 2.pdf", children: nil)
]),
File(name: "Photos", children: [
File(name: "Photo 1.jpg", children: nil),
File(name: "Photo 2.jpg", children: nil)
]),
File(name: "Empty folder", children: []),
File(name: "sys.info", children: nil)
]
Finally, here's the code that does all the magic. Simply add the children
parameter to the List
initializer and specify the key path to the optional children array. In the case of our File
struct, it's named children
.
var body: some View {
List(items, children: \.children) { item in
Image(systemName: item.icon)
Text(item.name)
}
}