UINavigationController And UITabBarController Programmatically (Swift 4)

Derrick Park
May 29, 2017 · 3 min read
Image for post
Image for post

UITabBarControllers & UINavigationControllers are the main controllers for iOS Development.They are a great way to navigate between a set of your ViewControllers. The iOS Clock app is a perfect example of using UITabBarController as the main way to control the app. There are tons of tutorials online on how to create UITabBarControllers and UINavigationControllers using interface builder, but to fully understand how they’re supposed to be used, it is good to know how to build it from the ground up programmatically.


Apple gives an awesome description.


“You use tab bar controller to organize your app into one or more distinct modes of operation. The view hierarchy of a tab bar controller is self contained. It is composed of views that the tab bar controller manages directly and views that are managed by content view controllers you provide. Each content view controller manages a distinct view hierarchy, and the tab bar controller coordinates the navigation between the view hierarchies.”

Let’s start!

(As a side note, we will create our controllers in the AppDelegate.swift for the simplicity sake. Also make sure to update the AppDelegate(window) and info.plist(delete Main.storyboard) for programmatic ViewControllers.)

1. Let’s create a Tab Bar Controller and 3 View Controllers.

Essentially, all we need to do is to create instances of our View Controllers and assign them to our Tab Bar Controller’s viewControllers property. So let’s first create a tabBarController.

let tabBarController = UITabBarController()

And then, go ahead and create three View Controllers (instances of our default ViewController). I will name them as favoritesVC, downloadsVC, historyVC and update the view’s title and backgroundColor property as orange, blue, and cyan respectively.

let favoritesVC = ViewController()
favoritesVC.title = “Favorites”
favoritesVC.view.backgroundColor = UIColor.orange
let downloadsVC = ViewController()
downloadsVC.title = “Downloads”
downloadsVC.view.backgroundColor = UIColor.blue
let historyVC = ViewController()
historyVC.title = “History”
historyVC.view.backgroundColor = UIColor.cyan

2. Create a button in our default ViewController and add a target action.

This step is optional but in order to see our viewControllers interact with navigation bar’s back button, we will add some button in our viewController. In viewDidLoad(), include the following:

let button: UIButton = UIButton(frame: CGRect(x: view.bounds.width / 2–50, y: view.bounds.height / 2, width: 100, height: 50))button.backgroundColor = UIColor.blackbutton.addTarget(self, action: #selector(pushToNextVC), for: .touchUpInside)self.view.addSubview(button)

I am placing the button in the center of our screen. Let’s add a function below the viewDidLoad() for the action.

func pushToNextVC() {
let newVC = UIViewController()
newVC.view.backgroundColor = UIColor.red
self.navigationController?.pushViewController(newVC, animated:

Here I am just creating a new view controller with a red background Color and push it to the navigation stack.

3. Set the tabBarItem for each ViewController.

Apple defines the tab bar item as follows :

Since we set the title of our view Controllers already, the default value of the tab bar items will be the same as the view controller’s title.

favoritesVC.tabBarItem = UITabBarItem(tabBarSystemItem: .favorites, tag: 0)downloadsVC.tabBarItem = UITabBarItem(tabBarSystemItem: .downloads, tag: 1)historyVC.tabBarItem = UITabBarItem(tabBarSystemItem: .history, tag: 2)

(I am using the default system items Apple for the tabs.)

4. Set the tabBarController’s viewControllers property to an array of our three viewControllers.

let controllers = [favoritesVC, downloadsVC, historyVC]tabBarController.viewControllers = controllers

5. Create and set a UINavigationController for each viewController.

t̶a̶b̶B̶a̶r̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶.v̶i̶e̶w̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶s̶ =̶ ̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶s̶
tabBarController.viewControllers = controllers.map { UINavigationController(rootViewController: $0)}

Here we replaced our previous code with the above code. Swift’s map function allows us to create a navigation controller for each view controller and return that as an array.

Let’s run our app!

Image for post
Image for post
That’s it!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

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