Navigation Controller Quickstart
Updated with iOS 27, Xcode 27 and Swift 6.4
Overview
Navigation controllers help a user browse through a hierarchy of content
by maintaining a history of view controllers that navigated to the
current one. This quickstart covers the basic procedure for setting up
and using a navigation controller.
Storyboard setup
Step 1: Embed root view controller inside a navigation controller
In your storyboard, select the initial view controller in your
hierarchy. With this view controller selected, choose the menu item
Editor -> Embed In -> Navigation Controller.
Step 2: Add components to control the navigation
Typically navigating to another view controller happens in response to
some user interaction. You’ll have to add some controls (e.g. buttons,
gesture recognizers, table views) to your root view controller to allow
the user to trigger the navigation.
In our demo example below we have added two buttons “Red” and “Blue”
that will trigger a navigation to new view controllers with red and blue
backgrounds.
Step 3: Create a segue to navigate to a new view controller
Add the view controller you want to navigate to in the storyboard. You
can trigger navigation in response to an action by control-dragging
from the component that would fire the action to the new view controller
and selecting show under Action Segues. This defines a transition
between the two view controllers called a segue.
In the example below we create two segues, one in response to a tap on
the “Red” button and the other in response to a tap on the “Blue”
button. This can be done for a wide variety of events. One typical
example is handling the row selection event in a table view by
control-dragging from a prototype cell.
Step 4: Set an identifier for the segue
We’ll need a way to figure out which segue is firing when we write the code
to configure the new view controller. You can set a unique identifier for each
segue in the Attributes Inspector after selecting it.
Step 5: Prepare view controller before navigating to it
To configure the new view controller to which we are navigating, we can
override the prepareForSegue method in the current
view controller. In this case, we check which segue was triggered and
change the background color of the destination view controller
appropriately.
class ViewController: UIViewController {
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as UIViewController
if segue.identifier == "redSegue" {
destinationVC.title = "Red"
destinationVC.view.backgroundColor = UIColor.systemRed
} else if segue.identifier == "blueSegue" {
destinationVC.title = "Blue"
destinationVC.view.backgroundColor = UIColor.systemBlue
}
}
}
Running this example gives us:
Programmatic setup
You can also set up a navigation controller programmatically. If you
need the navigation controller to be your root view controller the best
place to do this is in the scene delegate’s
scene(_:willConnectTo:options:)
method, which UIKit calls when your app’s scene connects. As of the iOS
27 SDK the scene-based life cycle is required — per the
iOS & iPadOS 27 release notes,
apps built with the latest SDK must adopt it or they fail to launch, so
older tutorials that create a UIWindow(frame: UIScreen.main.bounds) in
the AppDelegate no longer work. We’ll reimplement the same example as
above.
Since we’re creating the window ourselves, remove the
UISceneStoryboardFile
(“Storyboard Name”) entry under the Application Scene Manifest in the
target’s Info tab so UIKit doesn’t load the storyboard’s initial view
controller as well. We can still instantiate individual view
controllers from the storyboard manually, as shown below.
Step 1: Instantiate the root view controller for the navigation controller
In this case we load the color picker view controller from our example
above. In a non-storyboard application we would instantiate a view
controller here directly or by loading a nib with
initWithNibName.
// SceneDelegate.swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let pickColorVC = storyboard.instantiateViewController(withIdentifier: "PickAColor") as UIViewController
...
}
...
}
Step 2: Create navigation controller with root view controller
Here we create a navigation controller and provide it with the color
picker view controller as its root view controller. We then create the
window with
UIWindow(windowScene:)
and set the root view controller of the window object to be the
navigation controller.
// SceneDelegate.swift
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
...
let navigationController = UINavigationController(rootViewController: pickColorVC)
window = UIWindow(windowScene: windowScene)
window?.rootViewController = navigationController
window?.makeKeyAndVisible()
}
...
}
Step 3: Respond to events by pushing new view controllers
Here we respond to button taps by configuring a new view controller and
pushing it onto the navigation stack with pushViewController.
class ColorPickerViewController: UIViewController {
@IBAction func didTapRedButton(sender: Any) {
pushViewController(title: "Red", color: UIColor.systemRed)
}
@IBAction func didTapBlueButton(sender: Any) {
pushViewController(title: "Blue", color: UIColor.systemBlue)
}
private func pushViewController(title: String, color: UIColor) {
let vc = UIViewController()
vc.view.backgroundColor = color
vc.title = title
self.navigationController?.pushViewController(vc, animated: true)
}
}
Further reading
- Our Navigation Controller guide provides a more in depth look at navigation controllers
- Apple Documentation: UINavigationController
- Apple Documentation Archive: Navigation Controllers covers some of the more technical aspects of navigation controllers
