SwiftUI Field Guide

Scroll View

A scroll view lets us scroll content that's potentially too tall or wide to fit within a frame. Here's a simple example:

Code
ScrollView {    VStack {        Color.blue            .frame(height: 200)        MyLabel()        Color.green            .frame(idealHeight: 200)    }    .padding()}
Preview
250

We can specify along which axes a scroll view should scroll. The default is vertical. While a vertical scroll view always becomes exactly as tall as proposed, it has infinite vertical space available for its contents. During layout, a vertical scroll passes on its own proposed width, but it proposes nil for the height to its children. In other words, it tells its children to become their ideal height.

In the example below, we can see how the proposed value of the scroll view propagates through the view tree. Note that the green color has an ideal height, which gets used when the stack proposes a nil height. (If you're wondering why the VStack first propagates to the padded text, it's because it's the least flexible child.)

Preview
Tree

 

1/1
250

Gotchas

While a vertical scroll view accepts the proposed height unconditionally, it only becomes as wide as the width of its contents. For example, if we have a scroll view with a short text, the scroll view might end up not being the full available width. We can fix this by adding a flexible frame to the text.

Code
ScrollView {    VStack {        Color.blue            .frame(width: 30, height: 200)        Text("Hello, world.")            /* .frame(maxWidth: .infinity) */        Color.green            .frame(width: 30, height: 200)    }    .padding()}/* .background { Color.teal } */
Preview
250

A scroll view has special behavior around the safe area. By default, a scroll view will not clip to the safe area, but draws its content behind any insets. To make sure the scroll view's contents is always visible, it insets its content.