MacKuba

Kuba Suder's blog on Mac & iOS development

Stacks, Grids, and Outlines in SwiftUI

Categories: SwiftUI, WWDC 20 0 comments Watch the video

Stacks

New lazy stack views: LazyVStack and LazyHStack

They work just like the existing horizontal and vertical stacks, but they render their content incrementally as it becomes visible

Useful for very long lists built using VStack/HStack that had performance issues previously

There’s no point using lazy stacks for small local stacks that just lay out single views that are all visible on the screen together

If you’re unsure, use standard HStack/VStack by default, and only use lazy stacks for long content that’s scrolling and becomes a performance bottleneck

Grids

New grid views: LazyHGrid and LazyVGrid

They lay out subviews in a grid like collection view

LazyVGrid(columns: columns, spacing: 0) { … }

Grids require a definition of columns:

Constant number of columns:

var columns = [
  GridItem(spacing: 0),
  GridItem(spacing: 0),
  GridItem(spacing: 0)
]

Adaptive columns, number depends on the window size:

var columns = [
  GridItem(.adaptive(minimum: 300), spacing: 0)
]

Lists and outlines

Lists are more than just stacks of content – they support selection and scrolling etc.

Lists don’t need a Lazy variant, because list contents are always loaded lazily

Lists can now show hierarchical trees of items (outlines)

To make an outline list, provide a “children” keypath:

List(graphics, children: \.children) { graphic in
    GraphicRow(graphic)
}

To make collapsible list sections, use an OutlineGroup:

ForEach(canvases) { canvas in
    Section(header: Text(canvas.name)) {
        OutlineGroup(items, children: \.children) { graphic in
            GraphicRow(graphic)
        }
    }
}

You can also implement other views with parts that the user can collapse and expand like in an outline using DisclosureGroup:

DisclosureGroup(isExpanded: $expanded) {
  Contents()
} label: {
  Label(“Name”)
}

or:

DisclosureGroup(“Label”) { contents }