How it works
TableForEachContent is the table-row content that SwiftUI synthesizes when you drive a Table's rows with a ForEach. Rather than writing one TableRow per record by hand, you hand ForEach a collection and it produces a TableForEachContent value that conforms to TableRowContent, so the table can lay out, sort, and select across every element. Reach for it whenever a table's rows come from dynamic, data-driven content — a list of people, files, or any Identifiable model — instead of a fixed, statically declared set of rows.
Open the rows builder with a Table
A
Tableseparates its columns from its rows: the trailingrows:closure is a@TableRowBuilderwhere row content lives. HereTable(of: Person.self)declares the element type up front, and therows:builder is where aTableForEachContentvalue will be supplied.Produce the rows with ForEach over Identifiable data
Placing
ForEach(people)inside therows:builder is what creates aTableForEachContent. BecausePersonisIdentifiable(itsidis aUUID),ForEachcan give each row a stable identity, which the table uses to keep rows distinct across updates, selection, and sorting.Emit one TableRow per element
The
ForEachclosure returns the per-element row,TableRow(person), binding that record to the row.TableForEachContentis the aggregate of all thoseTableRowvalues — it adapts the dynamicForEachoutput into the staticTableRowContenttheTableexpects, so eachPersonis matched against the declared columns.Resolve cells through the declared columns
Each row produced by
TableForEachContentis rendered against the table'sTableColumndefinitions. TheTableColumn("Name")andTableColumn("Role")closures receive the boundperson, pullingperson.nameandperson.roleintoTextso the columns align with every row theForEachemits.
Person(name: "Dave", role: "Analyst") to the people array and the ForEach regenerates TableForEachContent with a fourth TableRow, so the table grows a row without touching the rows: builder.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 TableForEachContentDemo: View {
struct Person: Identifiable {
let id = UUID()
let name: String
let role: String
}
let people = [
Person(name: "Alice", role: "Engineer"),
Person(name: "Bob", role: "Designer"),
Person(name: "Carol", role: "Manager")
]
var body: some View {
Table(of: Person.self) {
TableColumn("Name") { person in
Text(person.name)
}
TableColumn("Role") { person in
Text(person.role)
}
} rows: {
ForEach(people) { person in
TableRow(person)
}
}
.padding()
}
}