The UINavigationController and UINavigationBar in Swift

Improve your user experience

Image for post
Image for post
Diagram by Steven Curtis

Unusually for one of these articles I’ve presented two separate Projects within the repo

Difficulty: Beginner | Easy | Normal | Challenging
This article has been developed using Xcode 12.1, and Swift 5.3

Prerequisites:

- You will be expected to be aware how to make a Single View Application in Swift

- One of the implementations assumes you can create a UIViewController programmatically

- The concepts described here are the same as those covered in stacks

Terminology

Stack: A data structure used to store objects Storyboard: A way to graphically layout the UI in Xcode UINavigationBar: A bar containing buttons for navigating within the hierarchy of screens UINavigationController: A container that stores view controllers in a stack

The image at the top of the article (repeated here for ease of reading)

Image for post
Image for post

Shows the app to which this article refers. However, that UINavigationController that would embed the UIViewController instances isn't shown.

Perhaps the best way to express this is to show the storyboard solution from the practical below:

Image for post
Image for post

We can see that the UINavigationController comes first, that is the UIViewController instances are managed by it.

What is happening is that a UINavigationController instance manages the navigation stack that can have any number of UIViewController instances. So at the bottom of the stack there is a root view controller, and pushed on top of this are any number of child view controllers.

We can think of the topmost UIViewController instance as being the one that can be is viewable to the end use.

Each time we put a new topmost UIViewController onto the stack, we call that push, each time we remove one we do so by using a pop.

Image for post
Image for post

The UINavigationBar is featured at the top of the navigation stack, and can be adjusted (and even hidden from view), but is commonly in use to give the user a method of moving back through the stack of UIViewController instances.

Create the Programmatic Version

There are going to be two files here — the ViewController.swift (which is what we get for free when creating a project), so perhaps copy and paste the following:

We then need to create a new file — SecondViewController.swift, which can be produced by using the menu system in Xcode: File>New>File..

Image for post
Image for post

and then select Swift File as the template

Image for post
Image for post

Of course call the file SecondViewController

Image for post
Image for post

which will then be filled with the following contents:

Although this isn’t really part of this tutorial (there is a full guide on this here but essentially you can select Main.storyboard in the project inspector:

Image for post
Image for post

then pressing the delete key (on your keyboard!)

Then the reference must be removed, the easiest way is to select the top level project file in the project inspector (mine is called ProgrammaticConstraints).

Image for post
Image for post

and then delete the Main Interface (which is usually set to Main) which can be deleted once again with the use of the delete key on the keyboard.

Image for post
Image for post

The third stage of this is deleting the reference in the .plist file.

Image for post
Image for post

then we need to update the SceneDelegate.swift file to programmatically load the first UIViewController instance, so replace the optional func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) function with the following:

Create the Storyboard Version

To embed the main ViewController UIViewController instance move to Main.storyboard on the left-hand side project navigator and select the main view controller.

Through the menu system we can then select Editor>Embed in>Navigation Controller as in the following image"

Image for post
Image for post

this then gives an updated Storyboard where the UIViewController instance ViewController is embedded in the UINavigationController

This results in the following:

Image for post
Image for post

We can then add a new UIViewController in the UIStoryboard by selecting the + icon in the top-right hand corner of the screen.

Image for post
Image for post

Then drag-drop the instance:

Image for post
Image for post

We then need to create a new file — SecondViewController.swift, which can be produced by performing File>New>File..

Image for post
Image for post

and then select Swift File as the template:

Image for post
Image for post

Of course call the file SecondViewController:

Image for post
Image for post

then fill in the contents with the following code:

which then needs to be linked to the view controller on the storyboard. Go back to Main.storyboard and select the UIViewController to change the class to SecondViewController as in the following image:

Image for post
Image for post

Then create a button in order to traverse to that second UIViewController instance.

In order to do so, we need to add a UIButton and drag it onto the view. So, with Main.storyboard selected, press + in the top-right hand corner.

Image for post
Image for post

If you are careful, you can drag it to the middle of a UIViewController and get the blue guide lines to show it is in the middle of the page. A quick double-click on the UIButton instance can mean that we can change the name to Go!

Image for post
Image for post

We can then control-click on the button towards the background and choose Center Horizontally in Safe Area then repeat the process for Center Vertically in Safe Area:

Image for post
Image for post

In order to traverse to the next UIViewController instance click on the button and press control and drag to the SecondViewController. Then we choose show:

Image for post
Image for post

Which then gives the following solution:

Image for post
Image for post

Then we need to change the background of ViewController to be green, and SecondViewController as red. The process for doing this is to select the relevant UIViewController instance and then the view within that, and for the ViewController choose green, and SecondViewController choose red.

Image for post
Image for post

Traverse Programmatically

We can move through the stack, and one small wrinkle is that the navigationController instance is an optional! This means that (in the same way as above we are putting to the stack”

Animated is the nice sliding animation that moves across the screen: usually you would want that to be true.

We can also pop the topmost view controller from the top of the stack, whih is usually the UIViewController instance that is visible to the user:

The navigation stack is actully an array! We can access that using the following:

and we can treat this like an array, that is use any array functions

Customize the UINavigationBar programatically

It is more than possible to change the tint color:

We can also set a background image (the PlaceholderImage is avaliable for you in the repo):

which shows the following effect:

Image for post
Image for post

Of course you can set the title on the UINavigationBar, and even change the text:

There is also a titleView that can be useful for a company logo (or similar):

Image for post
Image for post

The back button can also be adjusted: take a look at this!

We can add button items:

of course this would require the addition of an addTapped function:

Customize the UINavigationBar through the Storyboard

If we select the UIStoryboard it is possible to select the UINavigationController. Now there are several options you can select, as in the screenshot below:

Image for post
Image for post

However if you are working in a larger group of developers you would be well advised to use a programmatic method to change more of the options, as within the UIStoryboard this can be difficult to track and use.

Conclusion

I hope you have enjoyed following along in this tutorial. There are reams of Apple documents, both for the UINavigationController as well as the UINavigationBar.

As with anything in iOS it can be tricky to get the exact effect you want, but it is certainly possible and I hope this article is really helping you to move into the exciting development future.

If you’ve any questions, comments or suggestions please hit me up on Twitter

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store