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.