Skip to content

SwiftUI's View Trees: The Mental Model That Changes Everything

3 min read

  • #swiftui
  • #architecture

When I first started with SwiftUI, I found myself wrestling with seemingly simple layouts and state management. Despite reading Apple’s documentation, something was missing - a deeper understanding of how SwiftUI actually works. That’s where “Thinking in SwiftUI” by Chris Eidhof and Florian Kugler changed everything for me. Today, I want to share the key insights from its first chapter that transformed my understanding of SwiftUI.

The Mental Model That Changes Everything

The most crucial insight is this: SwiftUI operates on view trees, not individual views. Every SwiftUI interface you build is actually a tree of views. Let’s look at a simple example:

Text("Hello")
    .padding()
    .background(Color.blue)

While this looks like a simple chain of modifiers, SwiftUI sees it as a tree:

background
   ├─ padding
   │    └─ Text
   └─ Color

This tree structure is crucial because it affects:

  • How layout works
  • How state flows
  • How animations behave
  • Where and when updates happen

Why View Trees Matter

Understanding view trees helps explain many common SwiftUI behaviors. For example, consider these two seemingly similar pieces of code:

// Version 1
VStack {
    if isEnabled {
        Text("Enabled")
    } else {
        Text("Disabled")
    }
}

// Version 2
VStack {
    Text(isEnabled ? "Enabled" : "Disabled")
}

While both achieve the same visual result, they create different view trees. Version 1 swaps entire views in and out of the tree, while Version 2 just updates a property of a stable text view. This difference affects animations, state persistence, and performance.

Blueprint vs. Reality

Another key concept is understanding that your SwiftUI code creates a “blueprint” for your interface. Each time state changes, SwiftUI:

  1. Uses your code to create a new view tree (the blueprint)
  2. Compares it with the current interface
  3. Updates only what’s necessary

This explains why SwiftUI views are structs, not classes - they’re meant to be lightweight descriptions of your interface, not the interface itself.

Practical Implications

Understanding these concepts leads to better code decisions:

// ❌ Less efficient - recreates views unnecessarily
struct ContentView: View {
    @State private var user: User

    var body: some View {
        if user.isPremium {
            PremiumView(user: user)
        } else {
            BasicView(user: user)
        }
    }
}

// ✅ More efficient - stable view tree
struct ContentView: View {
    @State private var user: User

    var body: some View {
        UserView(user: user)
    }
}

struct UserView: View {
    let user: User

    var body: some View {
        Group {
            if user.isPremium {
                PremiumContent()
            } else {
                BasicContent()
            }
        }
        .animation(.default, value: user.isPremium)
    }
}

The second version maintains a more stable view tree, leading to smoother animations and better performance.

Key Takeaways

  1. Think in Trees: Visualize your interface as a tree structure rather than a flat collection of views.
  2. Stability Matters: Try to maintain stable view trees by changing view properties rather than swapping entire views when possible.
  3. Views are Blueprints: Your SwiftUI code describes what you want, and SwiftUI figures out how to efficiently update the actual interface.

Moving Forward

Understanding these fundamental concepts makes it easier to:

  • Debug layout issues
  • Optimize performance
  • Write more maintainable code
  • Learn new SwiftUI features

The next time you’re building a SwiftUI interface, try visualizing its tree structure. Ask yourself:

  • What does my view tree look like?
  • Are my views stable across updates?
  • Am I changing properties or swapping entire views?

This mental model will serve as a foundation for everything else you do in SwiftUI.

Practice Exercise

Try this: Take a complex view in your current project and draw its view tree on paper. Look for opportunities to make the tree more stable across state changes. You might be surprised by what you find!


This article is based on Chapter 1 of “Thinking in SwiftUI” by Chris Eidhof and Florian Kugler. The concepts discussed here lay the groundwork for understanding SwiftUI’s more advanced features.

Feel free to share this article and connect with me on X, LinkedIn, Github.