The UINavigationController and UINavigationBar in Swift
Improve your user experience
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
- 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
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)
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:
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.
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
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:
and then select Swift File as the template
Of course call the file SecondViewController
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:
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).
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.
The third stage of this is deleting the reference in the .plist file.
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"
this then gives an updated Storyboard where the
ViewController is embedded in the
This results in the following:
We can then add a new
UIViewController in the
UIStoryboard by selecting the + icon in the top-right hand corner of the screen.
Then drag-drop the instance:
We then need to create a new file —
SecondViewController.swift, which can be produced by performing
and then select Swift File as the template:
Of course call the file SecondViewController:
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:
Then create a button in order to traverse to that second
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.
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!
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:
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:
Which then gives the following solution:
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.
Push View Controller
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.
Pop View Controller
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:
Dealing with the array
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:
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):
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
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:
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.
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