Skip to content

How to use ViewThatFits in SwiftUI | SwiftUI Bootcamp #71

Displaying text that may vary in length — across Dynamic Type sizes, device widths, or different languages — is one of the hardest layout challenges in iOS. ViewThatFits solves it elegantly: you provide fallback variants from most verbose to most compact, and SwiftUI picks the first one that actually fits the available space.

What You'll Learn

  • How ViewThatFits works: it tries each child in order and picks the first one that fits
  • When to use ViewThatFits over manual truncation or fixed font sizes
  • How the available space is measured and what "fits" means to SwiftUI

Mental Model

Think of ViewThatFits like a sign painter who has three versions of a shop sign prepared: a full text version, an abbreviated version, and a short acronym version. The painter measures the wall, holds up the full sign — if it fits, great, done. If not, try the abbreviated one. If that doesn't fit either, use the acronym. The customer gets the most informative sign that actually fits the wall.

ViewThatFits does exactly this: it offers SwiftUI a ranked list of alternatives and lets the layout engine pick the best one that doesn't overflow.

Detailed Explanation

ViewThatFits was introduced in iOS 16. It accepts a list of views (via a @ViewBuilder closure) and selects the first one whose ideal size fits within the proposed size from the parent. It evaluates candidates in declaration order — the first view is the "best" version (most content), and subsequent views are progressively more compact fallbacks.

"Fits" means the view's ideal (unconstrained) size is less than or equal to the proposed size in the axes being checked. By default, ViewThatFits checks both horizontal and vertical axes. You can restrict it to just .horizontal or .vertical using ViewThatFits(in: .horizontal) when only one axis matters.

Under the hood, SwiftUI calls sizeThatFits on each candidate with the proposed bounds. The first candidate whose required size is within bounds is selected and rendered. Non-selected views are never laid out in the view hierarchy — only the winner appears.

ViewThatFits is particularly valuable for: text that must remain on one line (truncation is unacceptable), buttons that need to show full labels without clipping, and UI that must look polished across Dynamic Type accessibility sizes. It works at runtime — it responds to window resizing, rotation, and Dynamic Type changes without any extra code.

Code Structure

ViewThatFitsBootcamp.swift puts three Text views of decreasing length inside a ViewThatFits. The outer container has a fixed frame (.frame(height: 300)) and padding, creating a constrained space. By reducing the container width (via padding), the shorter fallback texts become selected — this is visible immediately in Xcode's preview with different size classes.

Complete Code

ViewThatFitsBootcamp.swift

swift
import SwiftUI

struct ViewThatFitsBootcamp: View {
    var body: some View {
        ZStack {
            Color.red.ignoresSafeArea()
            
            ViewThatFits { // Tries each view in order and shows the first one that fits
                Text("This is some text that I would like to display to the user!") // Longest — preferred
                Text("This is some text that I would like to display!")             // Medium fallback
                Text("This is some text!")                                          // Shortest fallback
            }
        }
        .frame(height: 300)   // Constrains the available height for the ViewThatFits evaluation
        .padding(50)          // The padding reduces available width, potentially triggering fallbacks
        .font(.headline)
    }
}

struct ViewThatFitsBootcamp_Previews: PreviewProvider {
    static var previews: some View {
        ViewThatFitsBootcamp()
    }
}

Code Walkthrough

  1. ZStack { Color.red.ignoresSafeArea() ... } — The red background fills the entire safe area, making the available space clearly visible. The ViewThatFits sits centered inside the ZStack.

  2. ViewThatFits { ... } — The container that picks its winner. Three Text views are declared in decreasing length. SwiftUI measures each in the order listed and selects the first that fits within the proposed bounds.

  3. Text("This is some text that I would like to display to the user!") — The preferred, most informative text. SwiftUI tries this first. If the available width can display this without wrapping (in .headline font), this is what you see.

  4. .frame(height: 300) and .padding(50) — These constrain the space available to ViewThatFits. The 50-point padding on each side reduces the effective width by 100 points. On smaller screens or with Dynamic Type, the first text may not fit and SwiftUI falls through to the shorter versions.

  5. .font(.headline) — Applied to the outer container, this font size is used when measuring all three candidate texts. Importantly, changing this to .largeTitle would increase the size of each candidate, making it more likely that SwiftUI picks a shorter fallback.

Common Mistakes

Mistake: Putting views in the wrong order (short to long instead of long to short)
ViewThatFits always picks the first view that fits. If you put the shortest text first, it will always be shown — even when there's plenty of space. Always declare views from most preferred (longest/richest) to least preferred (shortest/simplest).

Mistake: Using ViewThatFits when text truncation or minimumScaleFactor would be simpler
If you just need to prevent text from truncating on one line, .lineLimit(1) with .minimumScaleFactor(0.7) is a simpler solution. ViewThatFits is best when you have genuinely different content variants, not just the same text at different scales.

Mistake: Expecting ViewThatFits to work when all candidates don't fit
If even the smallest, shortest view doesn't fit the available space, ViewThatFits shows the last candidate anyway (the last one is always the final fallback, regardless of whether it fits). Design your fallback hierarchy so the last option always fits under any reasonable condition.

Key Takeaways

  • ViewThatFits evaluates children in declaration order and renders the first one whose ideal size fits within the available space — declare longest to shortest
  • It re-evaluates automatically on rotation, Dynamic Type changes, and window resizing with no extra code
  • Use it when you have genuinely distinct content alternatives; for simple scale-down needs, prefer minimumScaleFactor

Last updated: June 27, 2026

Released under the MIT License.