Mobile App with UITabBarController + Sliding Side Menus

In this blog post I am going to show you how to create a very useful application template which uses NavigationDrawer(sometimes called as hamburger or side menu) and UITabBarController. This is how our application will look when we are done with this tutorial:

Simulator-Screens-Together

Picture 1

As usual I will record a video tutorial and this time I will also describe the implementation here in this blog post. First comes the video:

With the help of UITabBarController we can let user switch between two views: First View & Second View(see the two buttons at the bottom of the view). And with the help of Navigation Drawer(based on MMDrawerController open source project) we can let user slide the middle view to reveal application Left Side view or Right side view. Additionally to sliding with their finger left or right to reveal the side menu user will be able to tap on the top left side or the top right side bar button item to toggle the side menu.

I will begin by creating UITabBarController with two views. However you can easily add more views than that.

There are number of ways how to create UITabBarController and in this tutorial I will use only one of them. You can watch this video tutorial(http://swiftdeveloperblog.com/uitabbarcontroller-example-in-swift/) I have recorded earlier which demonstrate other ways to create UITabBarController.  

The simplest way to create application with UITabBarViewController in Swift is to do following:

  1. Open your Xcode
  2. Click on File->New project
  3. From the presented options on the left side select iOS->Application and once iOS Application is selected, select Tabbed Application
  4. Click Next

CreateTabBarApplication

Picture 2

  1. Give your new application a name and do not forget to select Swift as programming language.

Once your new application is created you can select Main.storyboard and see that Xcode has created UITabBarController with two views connected to it: FirstViewController.swift and SecondViewController.swift. Run your application and see how it works.

The next step is very important. Do not skip it.


Create TabBarViewController

For the purpose of this particular example we will need to create one more view controller which will extend UITabBarViewController. You can give this new view controller any name but for now let’s call this new view controller TabBarViewController

To create new view controller follow these steps:

  1. From the top menu section called File select New
  2. Then select File and you will be presented with the following window:

NewViewController

Picture 3

  1. Select iOS->Source->Cocoa Touch Class and click next
  2. Give your new view controller a name TabBarViewController and make sure it is a subclass of UITabBarViewController. Here is a screenshot of my screen:

TabBarControllerExtendsUITabBarViewController

Picture 4

When your TabBarViewController is created we are ready to make use of it. We will assign this view controller to our UITabBarViewController created on Main.storyboard. To do that follow these steps:

  1. Select Main.storyboard
  2. On the Main.storyboard select UITabBarViewController. Like so:

SelectUITabBarViewControllerOnStoryBoard

Picture 5

  1. Open right side utilities panel and select “Show the Identity inspector” tab
  2. In the Custom class text field type the name of your TabBarViewController
  3. Do the same for Identity -> Storyboard ID like so:

IdentityInspector

Picture 6

We are now done setting up our UITabBarViewController and are ready to continue.  

Navigation Drawer

We are now going to create a Navigation Drawer for our app. But we are not going to create it from scratch and will rather make use of an open source project called “MMDrawerController”. I am a big fan of open source projects because most of the time they help to speed up the development time of your project drastically. Also, am not a creator of MMDrawerController and all the credits go to people mentioned on project’s page on github.

We will begin my downloading MMDrawerController from GitHub:

  1. Open this URL in your browser window https://github.com/mutualmobile/MMDrawerController
  2. Click on Download ZIP button to download ZIP archive of MMDrawerController project to your computer. Here is where the Download ZIP button is at the time of writing this text:

GitHubMMDrawerController

Picture 7

  1. Once the project is downloaded to your computer unzip the archive to see its content

At the moment of writing this text the MMDrawerController project is available only in Objective-C. But because Swift and Objective-C can integrate with each other very well we can easily make use of this project.

Let’s create a new Folder/Group in our project structure, so we can organize there MMDrawerController files.

  1. Open your Xcode project
  2. From the project files Navigator on the left side select the project’s root folder and do right mouse click on it to bring up the menu with options.
  3. From the menu options select New Group and give your new folder a name. For example: MMDrawer
  4. Now open the MMDrawerContoller project folder you have downloaded and unzipped and find inside of this folder another subfolder called ”MMDrawerController”. You will see many Objective-C .m and .h files. Select all of the files and drag and drop them into the MMDrawer folder you have created in Xcode. Xcode will prompt you with a window with a few options. I suggest you make the checkbox with a label “Destination” selected like so:

CopyItemsIfNeeded

Picture 8

  1. Click on Finish button.
  2. Since we are adding Objective-C and this is our first time doing it for this project, Xcode will prompt us with another dialog window asking if we want to create a Bridge Header file. Choose Yes. We do need a Bridge Header file so that we can use it to #import the MMDrawerController Objective-C files into our project.
  3. Xcode will create a Bridging Header header file inside of our subfolder called MMDrawer. The name of the bridging header file will be of the following structure <Your project name>-Bridging-Header.h
  4. Select Bridging-Header.h file and import there the MMDrawerController.h file. Like so:

ImportMMDrawerController

Picture 9

  1. Save the Bridging-Header file and this will make the MMDrawerController available to all of the ViewController files we create in our project. Which is very convenient!

We are now ready to integrate our UITabBarViewController and MMDrawerController and make the UITabBarViewController slide to reveal Left and or Right side panel.

 

Left side and Right side view controllers

Create UI for Left side and Right side view controllers

We will use Main.storyboard to host user interface files for the Left side and the Right side view controllers.

  1. Select Main.storyboard and reveal the right side Utilities panel
  2. At the bottom of the Utilities panel you should see the Objects library. If objects library is not visible, click on the circle button to reveal it. Like so:

ObjectsLibrary

Picture 10

 3. In the objects library find a View Controller object and drag and drop it into Main.storyboard. You can double click on an empty space in the Main.storyboard to make it zoom out, so you can see it better. I will drag and drop 2 new view controllers. One will be used for the Left side panel and another one for the Right side panel. I can hide my left side Xcode panel (Project Navigator) and the right side panel(Utilities panel), so that I have even more space to review my Main.storyboard. So my Main.storyboard will now look like this:

LeftAndRightsidePanels

Picture 11

Now when we have User Interface files created for each of the panels we need to create Swift files that will serve as ViewControllers for these interface files. I will create LeftSideViewController and RightSideViewController both of which will be a subclass of UIViewController.

To create a new View Controller for Left side reveal panel follow these steps:

  1. From the top side menu option called File select New
  2. Then select File
  3. Select iOS->Source and then Cocoa Touch Class and click Next
  4. For the Class name type in LeftSideViewController. From the Subclass drop down menu select UIViewController
  5. Select Swift as programming language. For example my options window looks like this:

LeftSideViewController

Page 12

  1. When done, Xcode will create a new Swift file called LeftSideViewController.h
  2. Repeat these same steps to create RightSideViewController Swift file.

The next step for us is to associate newly created LeftSideViewController and RightSideViewController with their interface files on Main.storyboard.

  1. Open Main.storyboard and select ViewController interface file we have created earlier
  2. Open Xcode right side Utilities panel and select Identity inspector tab
  3. Under Custom class type in LeftSideViewController. Make sure you do not make a typo here. Better copy and paste the view controller’s name rather than typing it.
  4. Under Identity->Storyboard ID also type LeftSideViewController

We are now done with the LeftSideViewController and below is how my screen looks like for this ViewController.

AssignLeftSideViewController

Page 13

Now repeat the above 4 steps to associate the RightSideViewController Swift file with the second Interface file on our Main.storyboard.

After you have done with the RightSideViewController we are ready to make use of these two view controllers and add them into our Navigation Drawer.

 

Create the Right and the Left side bar button items to reveal the side views

There are couple of ways user of our mobile app can reveal left side and right side views. They can either swipe with their thumb left or right or they can use bar button items at the top to tap and toggle the side view to open or close. So let’s proceed and create these two bar button items.

Bar button items are placed on UINavigationBar, so let’s imbed our FirstViewController and the SecondViewController into a UINavigationController first.

  1. Open Main.storyboard and select FirstViewController
  2. From the Top menu option, select Editor -> Embed in -> Navigation Controller
  3. Repeat the above step for the SecondViewController and imbed it into NavigationController as well.

After you embed both the FirstViewController and the SecondViewController into NavigationController your Main.storyboard will look like this:

LeftSideAndRightSideViewControllersEmbedded

Picture 14

Now when we have our FirstViewController and SecondViewController imbedded into NavigationController we can place the top bar button items.

  1. Open Main.storyboard and select FirstViewController
  2. Open up Xcode right side Utilities panel and make sure your objects library is selected
  3. In the Objects library find the Bar Button Item
  4. Select Bar Button Item and drag and drop it to the left side of NavigationBar. Your view controller should look like on the picture below:

FirstViewControllerLeftSideButton

Picture 15

Look at the arrow with label #7. There you can provide a custom title for the bar button. At this moment I will type into the Title field value of “Left” but I could also provide a custom image for the button and get rid of title string completely.

Repeat the steps above to place Bar button item on the right side of Navigation bar and give it a title “Right”. This way we will have two button items: “Left” and “Right”. Each of these bar button items will later toggle it’s relevant side menu to reveal it and close it.

 

Putting NavigationDrawer and UITabBarController together

We can now put our Left and Right side views as well as UITabBarController into one NavigationDrawer and run our application to see how it looks when views are assembled together.

Most of the code will be written in our AppDelegate.Swift file. So, let’s open the AppDelegate file and create a new function which we will call buildNavigationDrawer()

 func buildNavigationDrawer()
 {
 }

Inside of buildNavigationDrawer function we will need to instantiate TabBarViewController, LeftSideViewController and RightSideViewController and put them all together into a NavigationDrawer. To be able to instantiate views that have been created on Main.storyboard we will need to get access of it first.

let mainStoryBoard:UIStoryboard = UIStoryboard(name:"Main", bundle:nil)

Now when we have a reference to a Main.storyboard let’s instantiate the views we need one by one:

 let mainPage:TabBarViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("TabBarViewController") as! TabBarViewController
            
 let leftSideMenu:LeftSideViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("LeftSideViewController") as! LeftSideViewController
            
 let rightSideMenu:RightSideViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("RightSideViewController") as! RightSideViewController

Please note that we use instantiateViewControllerWithIdentifier and the value we give it is the value we provided in Identity->Storyboard ID. For example look at the Picture #13 above which illustrates how we set up the value of Storyboard ID for LeftSideViewController.

Next we need to wrap the LeftSideViewController and the RightSideViewController into UINavigationController. We do this because these two view controllers have Bar Button items on the left side and on the right side and if we do not wrap these view controllers into UINavigationController there will be no NavigationBar and the buttons will not be visible. So let’s take leftSideMenu and the rightSideMenu and wrap them into UINavigationController.

let rightSideMenuNav = UINavigationController(rootViewController:rightSideMenu)
let leftSideMenuNav = UINavigationController(rootViewController:leftSideMenu)

We now ready to put all of these together into MMDrawerController and because MMDrawerController will be accessed from other ViewControllers in our application let’s define it as an instance object of AppDelegate. So scroll all the way up to the top of your AppDelegate and define MMDrawerContoller above all functions like so:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var drawerContainer: MMDrawerController?

.... 

and now when we have defined MMDrawerController we can scroll down to our buildNavigationDrawer() function and create MMDrawerController like so:

drawerContainer = MMDrawerController(centerViewController: mainPage, leftDrawerViewController: leftSideMenuNav, rightDrawerViewController: rightSideMenuNav)

We are almost there! A couple more lines of code and we will be done setting up our MMDrawerContoller.

We need to enable center view Panning, so that user is able to swipe left and right to reveal the Left side view and the Right side view. We are going to use openDrawerGestureModeMask
and closeDrawerGestureModeMask of MMDrawerController like so:

drawerContainer!.openDrawerGestureModeMask = MMOpenDrawerGestureMode.PanningCenterView
drawerContainer!.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.PanningCenterView

and finally we need to assign our drawer controller to the rootViewController of our window.

window?.rootViewController = drawerContainer

So the complete buildNavigationDrawer() now looks like this:

 func buildNavigationDrawer()
    {
        
            // Instantiate Main.storyboard
            let mainStoryBoard:UIStoryboard = UIStoryboard(name:"Main", bundle:nil)
            
            // Create View Controllers
            let mainPage:TabBarViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("TabBarViewController") as! TabBarViewController
            
            let leftSideMenu:LeftSideViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("LeftSideViewController") as! LeftSideViewController
            
            let rightSideMenu:RightSideViewController = mainStoryBoard.instantiateViewControllerWithIdentifier("RightSideViewController") as! RightSideViewController
            
            
            
            // Wrap into Navigation controllers
            let leftSideMenuNav = UINavigationController(rootViewController:leftSideMenu)
            let rightSideMenuNav = UINavigationController(rootViewController:rightSideMenu)
            
            // Cerate MMDrawerController
            drawerContainer = MMDrawerController(centerViewController: mainPage, leftDrawerViewController: leftSideMenuNav, rightDrawerViewController: rightSideMenuNav)
            
            drawerContainer!.openDrawerGestureModeMask = MMOpenDrawerGestureMode.PanningCenterView
            drawerContainer!.closeDrawerGestureModeMask = MMCloseDrawerGestureMode.PanningCenterView
            
            // Assign MMDrawerController to our window's root ViewController
            window?.rootViewController = drawerContainer
        
    }

The buildNavigationDrawer() function is ready but this code will not run until we call it. The best place to call this function is from topmost function application didFinishLaunchingWithOptions. So let’s go up the page and add a call to buildNavigationDrawer() function.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
 
        buildNavigationDrawer()
        
        return true
    }

Now you can run your application and see how it works. You should be able to see the tab bar and be able to switch between the FirstView and the Second view. You should be able to swipe with you thumb left and right to reveal the Left side view and the right side view.

The top bar button items will not work at this moment because we did not write any code to make them work yet.

Enable Top Bar Button Items

Top Bar Button items should be placed in both the FirstViewController and the SecondViewController. I will show you how to enable them for the FirstViewController and you should be able to repeat these same steps and enable the Top Bar Button items for the SecondViewController as well.

  1. Open Main.storyboard, select FirstViewController and click on Assistant Editor icon.

FirstViewController_1

Picture 16

  1.  Select the Left Bar Button item, hold Control key on the keyboard, click drag and drop the blue connector like into your Swift code right before the ending curly bracket “}” of the class FirstViewController class.
  2. Select Action option for the Connection and give your action a name: leftSideButtonTapped and click on Connect button to complete.

FirstViewController_2

Picture 17

You should have a new function created:

@IBAction func leftSideButtonTapped(sender: AnyObject) {
}

When user taps on the left side top Bar Button item the leftSideButtonTapped function will be called. Let’s add inside of this function a code which will toggle the left side menu:

@IBAction func leftSideButtonTapped(sender: AnyObject) {
      
     // Access an instance of AppDelegate
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        
       // Reference drawerContainer object declared inside of AppDelegate and call toggleDrawerSide function on it
        appDelegate.drawerContainer?.toggleDrawerSide(MMDrawerSide.Left, animated: true, completion: nil)

    }

Repeat these steps for the Right side Top Bar Button item but keep in mind that to toggle Right side view we will need to use MMDrawerSide.Right instead of MMDrawerSide.Left like so:

appDelegate.drawerContainer?.toggleDrawerSide(MMDrawerSide.Right, animated: true, completion: nil)

Run your application and you should be able to toggle the left side view as well as the right side view by tapping on Top Bar Button items.


Conclusion

We are now done creating the Navigation Drawer base app which makes use of Tab Bar Controller as it’s central view when your mobile app starts up. This application is a good starting point for you to continue building up on top of it and customize Left side view, Right side view and other views as needed.

I hope this was helpful!