-
Notifications
You must be signed in to change notification settings - Fork 472
Navigation Controller Quickstart
Updated with iOS 17, Xcode 15.0.1 and Swift 5.9
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.
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
.
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.
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.
We'll need a way 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.
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:
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 app delegate. We'll reimplement the same example as above.
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
.
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let pickColorVC = storyboard.instantiateViewController(withIdentifier: "PickAColor") as UIViewController
...
}
...
}
Here we create a navigation controller and provide it with the color picker view controller as its root view controller. We also set the root view controller of the window object to be the navigation controller.
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
...
let navigationController = UINavigationController(rootViewController: pickColorVC)
window = UIWindow(frame: UIScreen.main.bounds)
if let window = window {
window.rootViewController = navigationController
window.makeKeyAndVisible()
}
return true
}
...
}
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.red)
}
@IBAction func didTapBlueButton(sender: Any) {
pushViewController(title: "Blue", color: UIColor.blue)
}
private func pushViewController(title: String, color: UIColor) {
let vc = UIViewController()
vc.view.backgroundColor = color
vc.title = title
self.navigationController?.pushViewController(vc, animated: true)
}
}
- 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