Chapters

Hide chapters

SwiftUI by Tutorials

Fifth Edition · iOS 16, macOS 13 · Swift 5.8 · Xcode 14.2

Before You Begin

Section 0: 4 chapters
Show chapters Hide chapters

13. Navigation
Written by Bill Morefield

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

It’s rare to find an app that can work with only a single view; most apps use many views and provide a way for the user to navigate between them smoothly. The navigation you design has to balance many needs:

  • You need to display data logically to the user.
  • You need to provide a consistent way to move between views.
  • You need to make it easy for the user to figure out how to perform a particular task.

SwiftUI provides a unified interface to manage navigation while also displaying data. SwiftUI 4.0 introduced significant changes to navigation for SwiftUI apps. In this chapter, you’ll explore building a navigation structure for an app using these new views.

Getting Started

Open the starter project for this chapter; you’ll find a very early version of a flight-data app for an airport. You’ll build out the navigation for this app. You would likely get the flight information from an external API in a real-world app. For this app, you’ll be using mock data.

To start, expand the Models folder in the app. Open FlightData.swift, and you’ll find the implementation of the mock data for this app. The FlightData class generates a schedule for fifteen days of flights with thirty flights per day starting with today’s date using the generateSchedule() method. The class uses a seeded random number generator to produce consistent flight data every time, with only the start date changing.

Now, open and examine FlightInformation.swift, which encapsulates information about flights. You’ll use this mock data throughout the following chapters.

Open WelcomeView.swift. The view includes a @StateObject named flightInfo that holds this mock data for the app.

Creating Navigation Views

Build and run the starter app. There’s a bare-bones implementation with a graphic and a single option to view the day’s flight status board.

Urubiuh ogh
Ojejoeb ehn

Cmluy Cuqoyejuut ir as aTxere
Clcaf Petinifaah op ew oRmoyi

Bnqah Jogiruvoed at id iHuf
Mssow Zinakogaek ib it iCur

Tufirud zenq Bosdk Kabeyadeeb Qicq
Fiwedel kojg Bimqb Lozevejoif Dasw

Polishing the Links

Before moving to the details view, you’ll improve the button’s appearance from the current plain text. Create a new SwiftUI View named WelcomeButtonView.swift. Replace the default view with the following:

Sspcih Bonives Qurrx
Srnwum Vupiwuf Yijyk

Building the Details View

Your details view will show the user a list of today’s flights. Open FlightStatusBoard.swift. At the top of the FlightStatusBoard struct, add a variable that you’ll use to pass in the list of flights for the day:

Vdiyyb pahl
Cxipfw fefp

Building a NavigationStack

With the two-column navigation you’ve created, you can implement the details views separately from the initial view. Your Flight Status option displays a list of today’s flights. Next, you’ll show information on a flight when the user taps it on the list. To do so, you’ll wrap this list inside a new NavigationStack implemented inside the overall NavigationSplitView details view.

Blewzf nuft tupd ebzeb
Rjegsq jihn lijz idgot

Fnebxt huhooyx maax
Rsigwp reciiqh yaux

Adding Items to the Navigation Bar

Creating a navigation view stack adds a navigation bar to each view. By default, the navigation bar only contains a button that returns to the previous view, except the first one. Beginning in iOS 14, the user can also long-press the back button to move anywhere up the view hierarchy in a single action.

Yunalevoev Sbifj
Nilidepaag Jsibk

Jincso
Qumkmu

Navigating With Code

As you saw earlier, passing data down the navigation stack is simple. You can send the data as a read-only variable or pass a binding to allow the child view to make changes that are reflected in the parent view. That works well for direct cases, but as the view hierarchy’s size and complexity increase, you’ll find that sending information back up can get complicated.

Madecujaik muewvon
Kirucivoiz lauvbod

Vilozqiy bkuprk ud Xehbizu yiup
Lawazkan gtellr ac Vijmuke jaes

Navigating Using Code

The last flight option you added to the sidebar in the previous section brings up the details for the flight. While it works, it’s a good idea to let the user go back from these details to the same list of flights like when they select the Flight Status option. Until now, your navigation changes have come from user interaction. You’ll find times like this when you want to trigger navigation through your code. In this section, you’ll see how to interact with the navigation stack through code and use this to make this change.

Btuhfb Hodiudf Xsunuqs Kpefsif Fifnxircos Jukanapeuj
Kqucvb Nusaagq Phowinh Jwerxiy Kugjsitxok Sogajucuoz

Using Tabbed Navigation

You’ve been using and building a hierarchical view stack with NavigationView up to this point in the app. Most apps use this structure, but there’s an alternative structure built around tabs. Tabs work well for content where the user wants to flip between options. In this app, you’ll implement tabs to show different versions of the flight status view.

Rcedxy yqakes wesy racc
Xxixwt lrufaf harm yest

Setting Tabs

Remembering the last tab selected when the user returns to the view would be a nice addition. To do that, in FlightStatusBoard.swift, below the hidePast state variable, add the following line:

Setting Tab Badges

SwiftUI 3.0 introduced controls that let you set a badge for each tab. This badge provides extra information to the user, but the available space limits the amount of data you can show. You’ll add a badge item to indicate the number of incoming and outgoing flights to the Flight Status and a short text badge showing the date.

Soqgal
Pucpop

Key Points

  • Starting in SwiftUI 4.0, navigation splits the declaration of a navigation action from the action to perform.
  • Split navigation can create a navigation structure with two or three columns. The framework will collapse the columns on small screen devices to appear identical to stack navigation.
  • Navigation stack creates a hierarchy of views. The user can move further into the stack and can back up from within the stack.
  • A NavigationLink shows a view that provides a value associated with the view. The navigationDestination modifier informs SwiftUI how to act when provided a value of a given type.
  • You apply changes to navigation views to controls in the stack and not to the navigation type itself.
  • You can access the view stack in your code by passing a binding to a mutable collection through the path parameter. In simple cases, this can be a collection of the type being used for navigation. If you need multiple types, you can use a NavigationPath.
  • Tab views display flat navigation that allows quick switching between the views.

Where to Go From Here?

To learn about migrating the older navigation types to the new ones introduced with SwiftUI 4.0, see Migrating to new navigation types at https://developer.apple.com/documentation/swiftui/migrating-to-new-navigation-types.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now