iOS Tab Bar Controller example

The UITabBarController class is a specialized view controller much like the tabs in your browser where each tab represents a specific view basically the site you are visiting. The tabs are created at the bottom of the window and each tab is associated with a specific view controller. Each tabs view can have its own look and feel as they may represent different functionality in your application. You can even add a navigation controller as one of the tab's view controller if needed. Tabbar items can be customized using image icons and specific titles. In this tutorial we will learn the following
  • Create a tab bar Controller programmatically
  • Associate view controllers to the tab bar controllers
  • Customize the look and feel of the tabs such as background color, text fonts, etc.
  • Set the title and image icons for the tab bar items
  • Go to a specific tab programmatically using a button click
iOS UITabBarController First Tab
iOS UITabBarController Second Tab
iOS UITabBarController Last Tab
Please Note: The tab bar has limited space for displaying your custom items. If you add six or more custom view controllers to a tab bar controller, the tab bar controller displays only the first four items plus the standard More item on the tab bar. Tapping the More item brings up a standard interface for selecting the remaining items.

For this example just create a New Project with the empty application template and then create 3 separate view controllers that represent our screens for display.

Interface file for the application delegate - MyTabViewAppDelegate.h

#import <UIKit/UIKit.h>

#import "MyUITabBarController.h"
#import "FirstViewController.h"
#import "SecondViewController.h"

@interface MyTabViewAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) MyUITabBarController *tabBarController;

@property (strong, nonatomic) FirstViewController *firstViewController;
@property (strong, nonatomic) SecondViewController *secondViewController;

@end

Implementation file for the application delegate - MyTabViewAppDelegate.m

#import "MyTabViewAppDelegate.h"

@implementation MyTabViewAppDelegate

@synthesize tabBarController;
@synthesize firstViewController, secondViewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    //create the view controller for the first tab
    self.firstViewController = [[FirstViewController alloc] initWithNibName:nil
                                                            bundle:NULL];
    
    //create the view controller for the second tab
    self.secondViewController = [[SecondViewController alloc] initWithNibName:nil
                                                            bundle:NULL];
    
    //create an array of all view controllers that will represent the tab at the bottom
    NSArray *myViewControllers = [[NSArray alloc] initWithObjects:
                                   self.firstViewController,
                                   self.secondViewController, nil];
    
    //initialize the tab bar controller
    self.tabBarController = [[MyUITabBarController alloc] init];
    
    //set the view controllers for the tab bar controller
    [self.tabBarController setViewControllers:myViewControllers];
    
    //add the tab bar controllers view to the window
    [self.window addSubview:self.tabBarController.view];
    
    //set the window background color and make it visible
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
    
}

- (void)applicationWillResignActive:(UIApplication *)application {
    //do nothing
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    //do nothing
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    //do nothing
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    //do nothing
}

- (void)applicationWillTerminate:(UIApplication *)application {
    //do nothing
}

@end

Interface file for the custom UITabBarController - MyUITabBarController.h

#import <UIKit/UIKit.h>

@interface MyUITabBarController : UITabBarController

@end

Implementation file for the custom UITabBarController - MyUITabBarController.m

#import "MyUITabBarController.h"

@interface MyUITabBarController ()

@end

@implementation MyUITabBarController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    //create a custom view for the tab bar
 CGRect frame = CGRectMake(0.0, 0.0, self.view.bounds.size.width, 48);
    UIView *v = [[UIView alloc] initWithFrame:frame];
    [v setBackgroundColor:[UIColor greenColor]];
    [v setAlpha:0.5];
    [[self tabBar] addSubview:v];
    
    //set the tab bar title appearance for normal state
    [[UITabBarItem appearance]
     setTitleTextAttributes:@{UITextAttributeTextColor : [UIColor whiteColor],
     UITextAttributeFont:[UIFont boldSystemFontOfSize:16.0f]}
     forState:UIControlStateNormal];
    
    //set the tab bar title appearance for selected state
    [[UITabBarItem appearance]
     setTitleTextAttributes:@{ UITextAttributeTextColor : [UIColor blueColor],
     UITextAttributeFont:[UIFont boldSystemFontOfSize:16.0f]}
     forState:UIControlStateHighlighted];
    
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Interface file for the first View - FirstViewController.h

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController

@end

Implementation file for the first View - FirstViewController.m

#import "FirstViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    NSLog(@"Initialize the first Tab");
    
    if (self) {
        //set the title for the tab
        self.title = @"First Tab";
        //set the image icon for the tab
        self.tabBarItem.image = [UIImage imageNamed:@"first.png"];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"View is displayed for the first Tab");
    
    //just display some text so that we know what view we are in
 UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 300, 100)];
    myLabel.text = @"First View Controller";
    myLabel.font = [UIFont boldSystemFontOfSize:24.0f];
    [self.view addSubview:myLabel];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Interface file for the second view - SecondViewController.h

#import <UIKit/UIKit.h>
#import "LastViewController.h"

@interface SecondViewController : UIViewController

@property (strong, nonatomic) LastViewController *lastViewController;

@end

Implementation file for the second view - SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

@synthesize lastViewController;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    NSLog(@"Initialize the second Tab");
    
    if (self) {
        self.title = @"Second Tab";
        self.tabBarItem.image = [UIImage imageNamed:@"second.png"];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"View is displayed for the second Tab");
    
    //just display some text so that we know what view we are in
 UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 300, 100)];
    myLabel.text = @"Second View Controller";
    myLabel.font = [UIFont boldSystemFontOfSize:24.0f];
    [self.view addSubview:myLabel];
    
    //create a button so that when the user taps it we will generate a new
    //tab programmatically
    UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    myButton.frame = CGRectMake(85.0f, 100.0f, 150.0f, 37.0f);
    [myButton setTitle:@"Add another Tab"
                forState:UIControlStateNormal];
    [myButton addTarget:self
                action:@selector(checkButtonClick:)
                forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:myButton];
    
}

- (void) checkButtonClick:(UIButton *)paramSender{
    
    UIButton *myButton = paramSender;
    
    //check which button was tapped
    if([myButton.currentTitle isEqualToString:@"Add another Tab"]){
        NSLog(@"Clicked on the button");
        
        //if the last view controller doesn't exists create it
        if(self.lastViewController == nil){
            LastViewController *lastView = [[LastViewController alloc] init];
            self.lastViewController = lastView;
            
            //Get the current array of View Controllers
            NSArray *currentControllers = self.tabBarController.viewControllers;
            
            //Create a mutable array out of this array
            NSMutableArray *newControllers = [NSMutableArray arrayWithArray:currentControllers];
            
            //add another view controller to the mutable array
            [newControllers addObject:lastViewController];
            
            //Assign the manipulated array to the tab bar Controller with animation
            [self.tabBarController setViewControllers:newControllers
                                             animated:YES];
            //display the tab that was just added 
            [self.tabBarController setSelectedIndex:(newControllers.count -1)];
            
        }
        
        
        
    }
    
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Interface file for the last view - LastViewController.h

#import <UIKit/UIKit.h>

@interface LastViewController : UIViewController

@end

Implementation file for the last view - LastViewController.m

#import "LastViewController.h"

@interface LastViewController ()

@end

@implementation LastViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    NSLog(@"Initialize the last Tab");
    
    if (self) {
        self.title = @"Just added";
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"View is displayed for the last Tab");
    
 UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 300, 100)];
    myLabel.text = @"Last View Controller";
    myLabel.font = [UIFont boldSystemFontOfSize:24.0f];
    
    [self.view addSubview:myLabel];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Reference