LavaUI docs GitHub

struct LazyVGrid

Swift

struct LazyVGrid<Data, Content> where Data : RandomAccessCollection, Content : View, Data.Index == Int

A vertically scrolling grid that mounts only the cells the viewport shows.

Must be placed directly inside a ScrollView(.vertical) — it needs that container's offset and height to know what is visible. Outside one it still renders correctly, by mounting everything, and says so once on stderr.

ScrollView(.vertical) {
    LazyVGrid(albums, cellWidth: 152, cellHeight: 233, spacing: 8) { album in
        albumCard(album)
    }
}

Cell state is not preserved across scrolling: a cell scrolled out of the window is unmounted, and @State inside it is gone when it returns. Keep anything that must survive in the model, which is where a list's selection and scroll position belong anyway.

Sources/LavaUI/LazyGrid.swift:42

Constructors

init(_ data: Data, cellWidth: Float, cellHeight: Float, spacing: Float = 0, maxColumns: Int? = nil, alignment: StackAlignment = .start, scrollTarget: Int? = nil, @ViewBuilder content: @escaping (Data.Element) -> Content)

Not documented.

alignment
what to do with the width left over after the last whole column. Cells have a fixed width, so a container is almost never an exact number of them across, and .start — the default — leaves the remainder as one uneven gap down the right-hand side. That reads as a list, which is right for one. .center splits it, which is right for a wall of cards with nothing to align to.

Sources/LavaUI/LazyGrid.swift:76

Properties

var alignment: StackAlignment

Where the columns sit when the container is wider than they need.

Sources/LavaUI/LazyGrid.swift:63

var cellHeight: Float

Height of every cell, in points. Fixed, which is what lets the grid work out which cells are visible without measuring any of them.

Sources/LavaUI/LazyGrid.swift:50

var cellWidth: Float?

Cell width in points. nil means one full-width column (LazyVStack).

Sources/LavaUI/LazyGrid.swift:47

var content: (Data.Element) -> Content

Builds the cell for one element. Called only for elements that are on screen.

Sources/LavaUI/LazyGrid.swift:68

var data: Data

The elements, one cell each.

Sources/LavaUI/LazyGrid.swift:45

var dumpDetail: String { get }

Not documented.

Sources/LavaUI/LazyGrid.swift:114

var maxColumns: Int?

Never lay out more than this many columns, whatever the width allows.

Changes what cellWidth/cellHeight mean: without it they are the cell's size and the container fits as many as go in, with it they are the smallest acceptable cell and its proportions, and the cells stretch to divide the row exactly. A wall of application icons wants the second — the count is the design and the size follows the display, rather than a fixed card leaving a wider and wider gutter as the screen grows.

Sources/LavaUI/LazyGrid.swift:61

var scrollTarget: Int?

Index whose cell should remain visible as keyboard selection moves. Nil leaves scrolling entirely under pointer/wheel control.

Sources/LavaUI/LazyGrid.swift:66

var spacing: Float

Space between cells, horizontally and vertically, in points.

Sources/LavaUI/LazyGrid.swift:52

Methods

func mountPrimitive() -> any AnyViewNode

Not documented.

Sources/LavaUI/LazyGrid.swift:126

func reconcilePrimitive(_ node: any AnyViewNode) -> any AnyViewNode

Not documented.

Sources/LavaUI/LazyGrid.swift:132

func structureLines(indent: Int = 0) -> [String]

Deliberately does not expand children. A structure dump of a lazy container that built every row would defeat the container's whole point, and on a large list would hang the dump.

Sources/LavaUI/LazyGrid.swift:122