Introduction
Container view controllers manage the content from multiple view controllers, and each have their own approach to view hierarchies. Certain container view controllers that you may encounter include
A navigation controller manages navigation going forward and back through a hierarchy of content view controllers. The navigation controller is usually used in conjunction with a navigation bar. The navigation bar can be helpful to orient the user with a title for the scene and a back button to return to the previous scene. The navigation bar can also be a useful location for additional buttons.
The navigation controller manages its view controllers in a navigation stack, which is an array of view controllers. The navigation controller’s root view controller will be the first view controller in the navigation stack. When the navigation controller navigates to a new scene, the new view controller is added to the stack. When the user selects the back button, the current view controller is removed from the stack.
So, a Navigation Controller acts as a frame around a root view. The root view displays data while the Navigation Controller provides a navigation bar at the top of every view that can show a title and buttons.
Every Navigation Controller needs exactly one root view. By itself, a Navigation Controller and its root view does nothing more than display data. What makes the Navigation Controller useful is when the root view connects to another view through a link called a segue.
A segue consists of an identifying name and a visual link from one view to another. The first view needs a button or some other item for the user to trigger the segue and make it display the second view. Then the Navigation Controller automatically displays a Back button on the navigation bar of the second view, which allows the user to return to the first view. The only code needed to display another view is this:
performSegue(withIdentifier: "segueIdentifier", sender: self)
firstLink
, and press ENTER.override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { performSegue(withIdentifier: "firstLink", sender: self) }
The purpose of this code is to identify the segue named firstLink
and follow that segue to open another view, which is the view with a different background color.
Each time you add a new View Controller to a storyboard, you need to do the following:
Background information
A UINavigationController
maintains an array of view controllers presenting related information in a stack. When a UIViewController is on top of the stack, its view is visible.
When you initialize an instance of UINavigationController
, you give it a UIViewController. This UIViewController is added to the navigation controller’s viewControllers
array and becomes the navigation controller’s root view controller. The root view controller is always on the bottom of the stack.
More view controllers can be pushed on top of the UINavigationController’s stack while the application is running. These view controllers are added to the end of the viewControllers
array that corresponds to the top of the stack. UINavigationController’s topViewController
property keeps a reference to the view controller at the top of the stack.
When a view controller is pushed onto the stack, its view slides onscreen from the right. When the stack is popped (i.e., the last item is removed), the top view controller is removed from the stack and its view slides off to the right, exposing the view of the next view controller on the stack, which becomes the top view controller.
Every UIViewController has a navigationItem
property of type UINavigationItem
. However, unlike UINavigationBar, UINavigationItem is not a subclass of UIView
, so it cannot appear on the screen. Instead, the navigation item supplies the navigation bar with the content it needs to draw. When a UIViewController comes to the top of a UINavigationController’s stack, the UINavigationBar uses the UIViewController’s navigationItem
to configure itself.
By default, a UINavigationItem is empty. At the most basic level, a UINavigationItem has a simple title string. When a UIViewController is moved to the top of the navigation stack and its navigationItem
has a valid string for its title property, the navigation bar will display that string.
A navigation item can hold more than just a title string. There are three customizable areas for each UINavigationItem: a leftBarButtonItem
, a rightBarButtonItem
, and a titleView
. The left and right bar button items are references to instances of UIBarButtonItem, which contain the information for a button that can only be displayed on a UINavigationBar or a UIToolbar.
Passing Data to Other Views
When an app displays multiple views in a Navigation Controller, data selected or entered in one view may need to be used in another view. Since the whole purpose of object-oriented programming is to isolate data, the solution is to pass data from one view to the other.
To receive data, a view needs the following:
var
keyword in this .swift file. Any data stored in a property can then be copied into any objects on the user interface connected by an IBOutlet variable.To send data, a view needs the following in its own .swift Cocoa Touch Class file:
To see how to pass data from one view to another in a Navigation Controller, follow these steps:
SecondViewController
.UIViewController
.SecondViewController
. This connects the SecondViewController.swift file to the second View Controller with the colored background.class SecondViewController
line.labelDisplay
. Then click the Connect button. Xcode creates an IBOutlet as follows:@IBOutlet var labelDisplay: UILabel!
Add the following underneath this IBOutlet:
var receivedString = ""
Edit the viewDidLoad
method as follows:
override func viewDidLoad() { super.viewDidLoad() labelDisplay.text = receivedString }
This viewDidLoad
method takes whatever data is stored in the receivedString
property and stores it in the labelDisplay.text
property so the text can appear on the label on the user interface.
Choose View > Standard Editor > Show Standard Editor, or click the Standard Editor icon in the upper right corner of the Xcode window.
Click the ViewController.swift file in the Navigator pane.
Add the following function in the ViewController.swift file:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { let nextVC = segue.destination as! SecondViewController nextVC.navigationItem.title = "Second View Title" nextVC.receivedString = "Passed text" }
Modifying the appearance of the Navigation Bar
To make a Navigation Controller look more appealing, you can change the color of the navigation bar or add Bar Button Items.
Some different ways to customize the navigation bar include
Modifying text for the Back Button
let customButton = UIBarButtonItem() customButton.title = "New back text" navigationItem.backBarButtonItem = customButton
Modifying the prompt and title text
override func viewDidLoad() { super.viewDidLoad() navigationItem.prompt = "Prompt text" navigationItem.title = "Title text" } //or override func prepare(for segue: UIStoryboardSegue, sender: Any?) { let nextVC = segue.destination as! SecondViewController nextVC.navigationItem.prompt = "Prompt text" nextVC.navigationItem.title = "Title text" }
The tintColor
property on the navigation bar (which is defined by the Navigation Controller) defines the color of the Back button text. The following code changes the Back button text to red, but you can choose any color.
navigationController?.navigationBar.tintColor = UIColor.red
The barTintColor
property defines the color of the navigation bar. Keep in mind that whatever color you choose for the navigation bar should contrast with any colors defined for the Back button to make it easy to see.
navigationController?.navigationBar.barTintColor = UIColor.green
Adding Buttons to a Navigation Bar
The navigation bar always displays a Back button on all but the root view. However, you can always add more buttons on the right side of the navigation bar. Then you can connect these buttons to IBAction methods to make them actually do something.