TechnologiesSwiftUI

TableRow struct

iOSmacOStvOSwatchOSvisionOS✓ renders

A row that represents a data value in a table.

How it works

A TableRow represents a single row of data inside a Table, pairing one element of your model with the columns that display it. When you build a table from a collection, SwiftUI synthesizes a TableRow for every element automatically; you reach for TableRow explicitly when you need to compose a table's rows by hand — interleaving groups, static rows, or rows from several sources — instead of handing Table a single uniform collection. It is the row-level building block that makes a Table value-driven, so each TableColumn knows which element to read from.

  1. Give each row an Identifiable element

    A TableRow is parameterized by one row value, and that value must be Identifiable so the table can track, diff, and select rows. In the example each Fruit conforms to Identifiable via its id = UUID(), which is exactly the identity a TableRow carries for a single fruit.

  2. Let Table synthesize rows from a collection

    When you initialize Table with a collection, SwiftUI wraps each element in a TableRow for you, so you never write TableRow by name. Passing fruits to Table(fruits) produces one implicit TableRow per Fruit element, which is the most common way to populate a table.

  3. Bind columns to the row's element with TableColumn

    Each TableColumn extracts a value from the row's element through a key path, and that element is precisely the value a TableRow holds. TableColumn("Name", value: \.name) and TableColumn("Color", value: \.color) read the name and color properties from each row's Fruit.

  4. Compose rows explicitly when content is non-uniform

    To build rows from more than a single collection — mixing sections, fixed rows, or multiple data sources — you place TableRow values directly in the table's row builder instead of passing one collection. The collection-based Table(fruits) form here is the shorthand; spelling out TableRow(fruit) for each element is the equivalent explicit form.

Try it — Replace Table(fruits) with an explicit row builder, e.g. Table(of: Fruit.self) { ... } rows: { ForEach(fruits) { TableRow($0) } }, to see the same rows produced by named TableRow values.

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.

TableRow.swift
struct TableRowDemo: View {
    struct Fruit: Identifiable {
        let id = UUID()
        let name: String
        let color: String
    }

    let fruits = [
        Fruit(name: "Apple", color: "Red"),
        Fruit(name: "Banana", color: "Yellow"),
        Fruit(name: "Grape", color: "Purple")
    ]

    var body: some View {
        Table(fruits) {
            TableColumn("Name", value: \.name)
            TableColumn("Color", value: \.color)
        }
        .padding()
    }
}
Live preview
Name Color Apple Red Banana Yellow Grape Purple
Name Color Apple Red Banana Yellow Grape Purple
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →