Recently I have seen people use tab bars that, when in landscape mode, run down the side of the iPad screen. I really like this as it takes up less screen space in general, but also that some of them are smaller in width than Apples own UITabBar, which at 59px I feel is larger than necessary. So in this tutorial I am going to show you how to create your own custom TabBar controller for managing multiple tabs. The entire source for this article can be downloaded from CustomTabBarExample. In response to this stack overflow question here is the DemoTabBar4.0. You can see the full video of this tutorial on YouTube.

Setting up the project.

First download the sample images from here. I have created both retina and non-retina make sure you only use the non-retina versions in interface builder. Opening up a new Xcode project and name the project CustomTabBarExample, unzip the example images and drag them into your project and with, Copying items into destination folder” selected hit finish.

Since we are creating a tab bar that will run down the side of the iPad in landscape mode set the supported device orientations to only support left and right landscape. This completes the setup of our blank project.

Building our CustomTabBarController

Select the Media Library, and drag out the background image for the CustomTabBar, placing it in the far left of the CustomTabBarController.

Notice that by adding image elements from the media library Xcode helpfully puts them inside a UIImageView for us. Add a UIView that covers the tab bar background and set its background colour to transparent. Add 3 buttons to this UIView. Each button has two images one dark grey and the other coloured (cyan or magenta). Set the darker of the two icons as the image for the button’s default state and the coloured image with the suffix _highlighted (this should really have been selected) for the selected state. Create an IBOutlet in the CustomTabBarViewController for the buttons UIView and hook it up so you can access them in code.

Note: These buttons could be added directly to the background UIImageView however, adding them to a UIView controller enables you to iterate through the buttons which as you will see later can be very useful.

Add a UIView that covers the remaining area of the CustomTabBarViewController, this will act as a placeholder for the content of the child views when switching tabs.

Create an IBOutlet in your CustomTabBarViewController class and to hook up the placeholder to it, be sure to synthesise this in the main.

Switching Tabs

Add a new UIViewController to your UIStoryboard and set its Size in the Attributes Inspector to be Freeform and uncheck resize from nib.

Select the UIView contained in the new UIViewController and in the size inspector set its dimensions to the same as those of the place holder (in this case they are 938,748). Copy this UIViewController two more times so we have one for each tab and set the background colour of each of the views housed in these UIViewControllers differently so you can see them change when you tap a tab.

In the CustomTabBarController implement the perform segue method like so.

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"HomeSegue"] 
       || [segue.identifier isEqualToString:@"HeartSegue"]
       || [segue.identifier isEqualToString:@"CogSegue"]){
        
        for (int i=0; i<[self.buttons.subviews count];i++) {
            UIButton *button = (UIButton *)[self.buttons.subviews objectAtIndex:i];
            [button setSelected:NO];
        }
        
        UIButton *button = (UIButton *)sender;
        [button setSelected:YES];
    }
}

Here you can see why adding the buttons to a UIView is useful, rather than having to comparing individual buttons we just need to loop through the buttons on the view to deselect the current selected item. Then select the button tapped to reflect the tab that is being shown.

Creating the Custom segue

Connect the Home button up to its UIViewController by right clicking on the button and dragging to the UIViewController, in the resulting popup choose custom as the transition style.

We now have to define what this custom transition will look like. We do this by creating a subclass of UIStoryboardSegue and overriding the perform method like so,

 
- (void) perform {
 
    CustomTabBarViewController *src = (CustomTabBarViewController *)self.sourceViewController;
    UIViewController *dst = (UIViewController *) self.destinationViewController;
 
    for(UIView *view in src.placeholderView.subviews){
        [view removeFromSuperview];
    }
 
    src.currentViewController = dst;
    [src.placeholderView addSubview:dst.view];
}

This implementation will take the source of the segue, in our case the CustomTabViewController and remove all of the subviews of the placeholder view we setup before finally adding the subview of the destination controller to the placeholder view. You will also note here that I have added another property to the CustomTabViewController called src.currentViewController, this keeps a handle to the UIViewController that owns the view being displayed. Now you have to set each of the Segues to be of this type to ensure this transition is indeed what is being used and create identifiers for each Segue. If you are using my code from above make sure they are named correctly, HomeSegue, HeartSegue and CogSegue.

You should complete this process for your remaining two UIViewControllers and your finished UIStoryboard should look something like this.

As you can see it is very simple to create your own custom transitions with very little code. I hope this helps you to create your own navigation items.