SwiftUI Hierarchical Table
A Table in SwiftUI is used to present data in rows and columns. It can display hierarchical data and can be used as a tree view.
To create a table insert a `Table` view and nested in there `TableColumn`s. To provide hierarchy, add a property to return the children or nil to the data record type and specify its keypath when configuring the `Table`.
import SwiftUI
class RecordGroup: ObservableObject, Identifiable {
let id: UUID = UUID()
@Published var name: String
@Published var value: Double
@Published var children: [RecordGroup] = []
var optChildren: [RecordGroup]? { children.isEmpty ? nil : children }
init (name: String, value: Double, children: [RecordGroup] = []) {
self.name = name
self.value = value
self.children = children
if !children.isEmpty {
self.value = children.map({ $0.value }).reduce(0.0, +)
}
}
}
struct SampleHierarchicalTableView: View {
@State private var records: [RecordGroup] = []
@State var selectedGroups: Set = []
var body: some View {
VStack(alignment: .leading) {
HStack {
Text("Table")
}
.font(.title)
Table(records, children: \.optChildren, selection: $selectedGroups, columns: {
TableColumn("Name", value: \.name)
TableColumn("Value", content: { rec in
Text(rec.value, format: .currency(code: Locale.current.currency?.identifier ?? "$"))
.bold(!rec.children.isEmpty)
})
.alignment(.numeric)
})
}
.task() {
records = [
RecordGroup(
name: "Earnings",
value: 1120,
children: [
RecordGroup(name: "Tax Return", value: 50),
RecordGroup(name: "Interest", value: 70),
RecordGroup(name: "Payment", value: 1000)
]),
RecordGroup(
name: "Expenses",
value: 200,
children: [
RecordGroup(name: "Groceries", value: 80),
RecordGroup(name: "Insurance", value: 100),
RecordGroup(name: "Bicycle repair", value: 20)
]),
RecordGroup(name: "Assets", value: 0, children: [
RecordGroup(name: "Painting", value: 580),
RecordGroup(name: "Cash", value: 2100),
])
]
}
}
}
#Preview {
SampleHierarchicalTableView()
}