← All daysDay 10 of 49 · Part 3: Views and layout
Day 10

How layout works: frames and sizing

These are the lesson notes for this day. Its build-along tutorial and flash cards have not been written yet.

Lesson 11

How layout works: frames and sizing

SwiftUI layout is a three-step negotiation, repeated all the way down the view tree. First, the parent proposes a size to the child. Second, the child chooses its own size — the parent cannot force it. Third, the parent positions the child. One consequence surprises everyone at first: a .frame() modifier does not resize the view it is attached to. It creates a new, invisible container of that size and places the view inside it.

The tools that follow from this: .frame(maxWidth: .infinity) makes a view accept all the width it is offered. .fixedSize() makes a view ignore the proposal and use its ideal size. .layoutPriority() decides which sibling is offered space first. containerRelativeFrame sizes a view relative to the scroll view around it. GeometryReader tells you the proposed size, for the cases where you need the number itself.

Exercise

Put a long Text in a narrow HStack beside an image. Make it truncate, then wrap, then refuse to shrink by adding .fixedSize(). Explain each result in terms of the three steps.

After this lesson you should be able to answer
  1. What are the three steps of SwiftUI layout?
  2. What does .frame(width: 100) actually do to the view it is applied to?
  3. Why does .frame(maxWidth: .infinity) make a button as wide as its container?
Resources