List maps a collection to rows through a stable id, which is what lets SwiftUI animate
inserts, removals, and reorders. Since iOS 15 it covers the full UITableView feature set:
sections, selection, swipe actions, and separator styling.
Data, Sections, Trees
List(messages, id: \.id) { message in
Text(message.content)
}
The id keypath must point at a stable property, such as a database key. Group rows with
Section(header:) and ForEach per section. A dedicated initializer renders recursive
data: pass a keypath to the optional children array and the list traverses the tree with
disclosure arrows.
struct Tree<Value: Hashable>: Hashable {
let value: Value
var children: [Tree<Value>]? = nil
}
List(tree, id: \.value, children: \.children) { item in
Text(String(item.value))
}
Selection
Selection works only in edit mode: pass a selection binding and put an EditButton in the
toolbar. The binding's type picks the mode: Set<UUID> enables multi-select, an optional
single id (UUID?) enables single-select.
@State private var selection: Set<UUID> = []
List(selection: $selection) {
ForEach(messages, id: \.id) { message in
Text(message.content)
}
}
.toolbar { EditButton() }
Swipe Actions
Attach swipeActions to a row, per edge, with several buttons if needed. role: .destructive colors the delete red; tint colors the others. allowsFullSwipe: true lets
a long swipe trigger the first action. iOS 15+.
Text(message.content)
.swipeActions(edge: .trailing, allowsFullSwipe: true) {
Button("Delete", role: .destructive) {
messages.removeAll { $0.id == message.id }
}
}
.swipeActions(edge: .leading, allowsFullSwipe: false) {
Button("Favorite") { }.tint(.yellow)
Button("Move") { }.tint(.green)
}
Styling
Styles are plain, sidebar, inset, grouped, and insetGrouped (the default). The
listStyle modifier propagates through the environment to every list below it.
headerProminence(.increased) makes a section header bigger and bolder. Separator control
is per row and per section: listRowSeparator, listRowSeparatorTint,
listSectionSeparator, listItemTint.