SwiftUI Navigation: Sheets & Popovers, Part 1

Episode #162 • Oct 4, 2021 • Subscriber-Only

It’s time to look at a more advanced kind of navigation: modals. We will implement a new feature that will be driven by a sheet and can be deep-linked into. Along the way we’ll introduce a helper to solve a domain modeling problem involving enum state.

Sheets & Popovers, Part 1
Adding inventory items
Enum binding transformations
Saving new inventory items
Deep-linking into the add sheet
Deep-linking with item data
Next time: deriving optional behavior

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.


So, that’s the basics of tab views, alerts and confirmation dialogs in SwiftUI, and it’s all looking pretty promising. We are able to drive these very basic navigation interactions purely with state changes. We can flip a single field to change the selected tab at the root, or we can flip a field to be non-nil and instantly get an alert showing.

We are seeing the beginnings of what it means to model navigation in state as well as how one can instantly support deep linking by just constructing the piece of state that corresponds to the navigation, and just let SwiftUI do the rest.

But so far the “navigation” we have explored is quite simple. Tab views have all of their child views present at once and then a simple binding controls which tab is currently active. And alerts are presented and dismissed via a transient piece of optional state, but the alert itself has no real behavior. It’s just some data and a few buttons that can invoke some actions.

Navigation starts to get really complicated when things can nest so that you can navigate to one screen, and then from there navigate to another screen, and on and on, and each screen picks up behavior of its own. That’s when modeling navigation in state starts to really take the form of a tree.

To get our feet wet in exploring this we are going to start with sheets in SwiftUI, which are modal screens that slide up over the main content of the screen. Sheets sit somewhere between tab views and alerts on the spectrum of navigation. They are presented and dismissed with optional state like alerts, but they can also hold onto complex behavior of their own like tab views.

We need to figure out how we can spin up a new view model to hand to the sheet when it’s presented so that it can have behavior, and then tear down the view model when the sheet is dismissed.

That’s going to take some time to get right, so let’s jump in.

This episode is for subscribers only.

Subscribe to Point-Free

Access this episode, plus all past and future episodes when you become a subscriber.

See plans and pricing

Already a subscriber? Log in


SwiftUI Navigation

Brandon Williams & Stephen Celis • Tuesday Nov 16, 2021

After 9 episodes exploring SwiftUI navigation from the ground up, we open sourced a library with all new tools for making SwiftUI navigation simpler, more ergonomic and more precise.

Collection: Derived Behavior

Brandon Williams & Stephen Celis • Monday May 17, 2021

The ability to break down applications into small domains that are understandable in isolation is a universal problem, and yet there is no default story for doing so in SwiftUI. We explore the problem space and solutions, in both vanilla SwiftUI and the Composable Architecture.

WWDC 2021: Demystifying SwiftUI

Matt Ricketson, Luca Bernardi & Raj Ramamurthy • Wednesday Jun 9, 2021

An in-depth explaining on view identity, lifetime, and more, and crucial to understanding how @State works.

@StateObject and @ObservedObject in SwiftUI

Matt Moriarity • Friday Jul 3, 2020

An in-depth article exploring the internals of @ObservedObject and @StateObject in order to understand how they are created and torn down.