How it works
TupleTableColumnContent is the conformance that lets a fixed group of table columns act as a single unit of TableColumnContent. When you list several columns inside a table's content builder, SwiftUI packs them into a tuple-backed value so the table knows, at compile time, exactly how many columns it has and the type of each. You rarely name this type yourself — it is the static, heterogeneous counterpart to the dynamic columns produced by ForEach, and you reach for it implicitly every time you write columns side by side rather than generating them in a loop.
Declare columns in a @TableColumnBuilder closure
A Table's trailing closure is a column builder. When you place more than one column in it, the builder combines them into a TupleTableColumnContent rather than a single column. In the example, the closure holding
TableColumn("Name", value: \.name)andTableColumn("Role", value: \.role)resolves to a two-element tuple content forTable(people).Each element is a TableColumn over the same row type
Every column folded into the tuple must describe the same RowValue — here
Person— so the table can render one cell per column for each row.TableColumn("Name", value: \.name)andTableColumn("Role", value: \.role)each map a key path onPersonto a column, and TupleTableColumnContent carries both with their distinct sort and comparator information preserved.Column count is fixed by the tuple's arity
Because the columns live in a tuple, their number and order are part of the type and cannot change at runtime. The two
TableColumnentries in the closure give a fixed two-column layout forTable(people); to vary columns by data you would switch toForEachinside the builder, which yields dynamic content instead of TupleTableColumnContent.Sorting and value key paths flow through unchanged
Wrapping columns in a tuple does not alter their behavior — TupleTableColumnContent simply forwards each column's value and comparability. Since
\.nameand\.roleare KeyPaths to Comparable String values, the columns remain individually sortable, and the table can build its sort descriptors from the tuple's members.
TableColumn("ID", value: \.id.uuidString) line beside the existing two columns and watch the tuple grow to a three-column table without any other change.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct TupleTableColumnContentDemo: View {
struct Person: Identifiable {
let id = UUID()
let name: String
let role: String
}
let people = [
Person(name: "Ada Lovelace", role: "Engineer"),
Person(name: "Alan Turing", role: "Designer"),
Person(name: "Grace Hopper", role: "Manager")
]
var body: some View {
Table(people) {
TableColumn("Name", value: \.name)
TableColumn("Role", value: \.role)
}
.padding()
}
}