Using The Navigation Bar Title and Back Button in Swift 3.0

In writing the Swift Swift View Controllers book, it came to my attention many people don’t understand the functionality of the navigation toolbar’s title and Back button. In an early part of writing, I planned to skip the topic as a minor detail  so I could get the book done and published. However, the built-in features of the navigation toolbar make it a powerful and useful feature that can’t be missed.

Setting Up the Storyboard

Open up a new single view project named NavBarDemo using Swift as the language and Universal device. Go to the storyboard and click the view controller icon in the scene. In the drop down menu, select Editor>Embed in>Navigation controller. Drag two buttons, one labeled Pizza and the other labeled Pasta out to the scene. Set the font size on both to 26 Point. Make the Pizza button White(#FFFFFF) text on a Red(#FF0000) background. Make the Pasta button White(#FFFFFF) text on a Blue(#0000FF) background. Arrange them like this on the storyboard:

2016-06-22_06-17-09

Select the Pizza button. Click the  auto layout pin button pinMenuButton. Pin the Pizza button 0 points up, 0 left, 0 right, and 0 down like this:

2016-06-22_06-22-30

Add the four constraints without updating. Select the Pasta button. Click the pin button pinMenuButtonand repeat the constraints of   0 up, 0 left, 0 right, and 0 down. Add the four constraints. Now Control-drag from the Pizza button to the Pasta button. Select Equal Widths in the menu that appears.

2016-06-22_06-30-19

On the auto layout resolver menu resolver button, select Update Frame in the All Frames in View section.

2016-06-22_06-31-40

Your controller should look like this:

2016-06-22_06-34-58

Drag two more view controllers on to the storyboard. Make the background of one Blue(#0000FF) and the background of the other Red(#FF0000).

Control drag from the Pizza button to the red scene. Select a show segue.

2016-06-22_06-38-52

In the attributes inspector, set the segue identifier to pizza. Control-drag from the Pasta button to the blue scene. Select a show segue. In the properties inspector, set the segue identifier to pasta. Your storyboard should look like this:

2016-06-22_06-41-09

In this lesson we will do all the coding in ViewController, so there is no need of code in the two new controllers.

Setting the Navigation Title Bar

There is a property on UIViewController called navigationItem. When used with navigation controllers, this controls the navigation bar at the top of the view. The navigationItem property is an instance of UINavigationItem, which has four major properties: a title, a left bar button, a right bar button and a prompt. To set the title on the toolbar , you set the string for the title property. For example add this to the ViewController class

override func viewWillAppear(_ animated: Bool) {
        navigationItem.title = "One"
    }

Build and run. The root view now has One as a title.

2016-06-22_06-59-59

We used viewWillAppear and not viewDidLoad. ViewController is the root view controller in the navigation stack. It only loads once and stays active in the background. It will execute viewDidload only once. To make sure we update, we use viewWillAppear instead.
The title is dynamic. As a simple example, We’ll place a count in the title of the navigation bar. Add the following code:

var vcCount:Int = 0{
    didSet{
      navigationItem.title = "Count: \(vcCount)"
    }
  }

We used the  didSet property observer feature of Swift. Any time vcCount changes, the title changes with it. We change the count on any segue so we can increment in prepare for segue:. Add this:

override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
        vcCount+=1
    }

It’s rare to not have a statement within an if clause in a prepare for segue:. We want any segue to increment the count, so we don’t need the if.

We want to show the count when we load. Change the viewWillAppear to this:

 override func viewWillAppear(_ animated: Bool) {
        // navigationItem.title = "One"
        navigationItem.title = "Count: \(vcCount)"
    }

Build and run. Go back and forth in the views. The title changes every time you come back to it.

2016-06-22_07-04-28

Programming the Back Button

You’ll notice once you have a title, the navigation Back button disappears, to be replaced by the previous view’s title.

2016-06-22_07-08-42

The Back button reads the controller underneath the current controller for its title. You cannot set the back button title directly. Instead, you set the title of the current controller before you leave for the destination controller. If the previous view controller’s title is nil, the button titles itself Back. Change the prepare for segue: to this:

override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
        vcCount += 1
        navigationItem.title = nil
    }

Build and run.
You have the count on the root controller

2016-06-22_07-14-16

You have a Back button on the child controllers

2016-06-22_07-14-26

If you wanted to add your own text to the Back button, you have to change the title of the controller directly under it on the navigation stack. The simplest way is change the title just before you segue to the new controller. Change prepare for segue: to this:

override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
        vcCount += 1
        navigationItem.title = nil

        if segue.identifier == "pizza"{
            navigationItem.title ="Pizza to One"
        }
        if segue.identifier == "pasta"{
            navigationItem.title = "Pasta to One"
        }
    }

Before we segue to the pizza and pasta controller, we change the title of the current controller’s navigationItem. The Back button reads the title of navigationItem and sets the button’s title accordingly. The viewWillAppear method will reset the title to the count in the first view controller when we pop the Pizza or Pasta view controller. Build and Run. Select to the Pizza and Pasta buttons:

2016-06-22_07-30-59

2016-06-22_07-30-05

To see this happening, you can comment out this in viewWillAppear.

//navigationItem.title = "Count: \(vcCount)"

Build and Run. When you go back, the title remains:

2016-06-22_07-33-30

Uncomment the line before you go on.

The Size Sensitive Back Button

The Back button is sensitive to the space around it. The button’s title responds to not having enough space to place itself. Change prepare for segue: to this:

    override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
        vcCount += 1
        navigationItem.title = nil
        if segue.identifier == "pizza"{
            let vc = segue.destinationViewController as UIViewController
            vc.navigationItem.title = "View Controller Pizza One"
            navigationItem.title = "Pizza to One"
        }
        if segue.identifier == "pasta"{
            let vc = segue.destinationViewController as UIViewController
            vc.navigationItem.title = "View Controller Linguine all’arrabbiata"
            navigationItem.title = "Pasta to One"
        }
    }

We get the destination view controller and assign it to vc. We then send the title for the destination view controller  to vc.navigationItem.title. We’ve picked some long labels to test size restrictions.

Set the simulator to iPad Air 2. Build and run. Select the Pizza button.

2016-06-22_07-58-45

Go back to select the Pasta button.

2016-06-22_07-45-03

That works as we expected. Now try an iPhone 6 in the simulator. Run the demo, select the Pasta controller and you get this:

2016-06-22_07-57-14

The navigation controller title gets replaced with Back. Go back and try the Pasta Button.

2016-06-22_07-51-03

There is only the  2016-06-22_08-10-17 icon and no text for the back button. Rotate the device by pressing Command-Left Arrow:

2016-06-22_08-08-46

The text re-appears with more space to place the text.

The back button is intelligent. If it has enough space, it displays the title of the previous controller. If there is not enough space, it displays Back. If there is not enough space for the word Back, it displays only the 2016-06-22_08-10-17 icon.
There is an important design rule in play here that I am intentionally breaking to make the point: Keep your titles short in a navigation bar. If you keep titles short, you will have the full functionality of the back button.

The Whole Code

ViewController.swift

//
//  ViewController.swift
//  NavBarDemo for Swift 3.0
//
//  Created by Steven Lipton on 6/22/16.
//  Copyright © 2016 Steven Lipton. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    var vcCount:Int = 0{
        didSet{
            navigationItem.title = "Count: \(vcCount)"
        }
    }
    
    override func viewWillAppear(_ animated: Bool) {
        //navigationItem.title = "One"
        navigationItem.title = "Count: \(vcCount)"
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
        vcCount += 1
        navigationItem.title = nil
        if segue.identifier == "pizza"{
            let vc = segue.destinationViewController as UIViewController
            vc.navigationItem.title = "View Controller Pizza One"
            navigationItem.title = "Pizza to One"
        }
        if segue.identifier == "pasta"{
            let vc = segue.destinationViewController as UIViewController
            vc.navigationItem.title = "View Controller Linguine all’arrabbiata"
            navigationItem.title = "Pasta to One"
        }
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

4 thoughts on “Using The Navigation Bar Title and Back Button in Swift 3.0”

  1. Many people tend to ignore the navigation controller basic prperties. This article covered toolbar title and back button precisely and also gave a overview on Auto Layouts.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s