Grid (iOS 16) lays out all children eagerly, so columns align strictly across rows, which the lazy grids cannot promise. Use Grid by default and switch to LazyVGrid or LazyHGrid only when a large data set makes eager layout too slow.
Rows and Columns
Each view inside a GridRow becomes a column. The grid's alignment and spacing apply to every cell, and each row can override its own vertical alignment.
Grid(alignment: .leading, horizontalSpacing: 10, verticalSpacing: 10) {
ForEach(users) { user in
GridRow(alignment: .firstTextBaseline) {
Text(user.name)
Text(user.familyName)
Text(user.age.formatted())
}
}
}
Spanning Columns
A one-cell GridRow renders in the first column only. Span it with gridCellColumns, or place the view directly inside the Grid without a GridRow and it fills the full width.
GridRow {
Rectangle()
.fill(.secondary)
.frame(height: 1)
.gridCellColumns(3)
}
Per-Cell Alignment
gridColumnAlignment overrides the grid alignment for one column, and gridCellAnchor places the content at an arbitrary unit point.
Text(user.age.formatted())
.gridColumnAlignment(.trailing)
Text(user.age.formatted())
.gridCellAnchor(.init(x: 0.25, y: 0.0))
Taming Flexible Views
Shapes and dividers expand to all available space and widen their column. gridCellUnsizedAxes stops that: the view then respects the width the other rows produced.
GridRow {
Rectangle()
.fill(.secondary)
.frame(height: 1)
.gridCellColumns(3)
.gridCellUnsizedAxes([.horizontal])
}