iOS desde Cero: Tab Bar Controller (UITabBarController)

Publicado el 05 agosto 2013 por Codehero @codeheroblog

En el capítulo anterior de la serie iOS desde Cero, hablamos sobre como crear aplicaciones con varias vistas y como cambiar de una a otra. En el capítulo de hoy continuaremos hablando de aplicaciones con múltiples vistas pero utilizando el controlador tab bar.


Creando el proyecto

Abramos Xcode para crear un nuevo proyecto. Vamos a File -> New -> Project…

Seleccionamos “Application” en la sección de iOS y hacemos doble click en “Tabbed Application”.

Le damos un nombre a nuestro proyecto, seleccionamos arc (automatic reference counting) y guardamos.

Explorando el código generado

Si observamos nuestro navegador de archivos, nos encontraremos con que Xcode ha generado un conjunto de clases por nosotros.

Corramos el proyecto para ver que hace este código.

Vemos que tenemos una aplicación con un tabbar de dos botones.

Vamos a abrir FirstViewController.xib. Observamos una vista que contiene un label, un textview y una barra negra en la parte inferior que parece representar el tabbar, pero en realidad no lo es. Esta barra simula la presencia del tabbar. Si hacemos click sobre ella, podemos notar que en el Attribute Inspector, en su sección Simulated Metrics, al atributo Bottom bar está asignado el valor Tab bar. Esto es simplemente para ayudar al desarrollador a visualizar el look final, podemos dejar de asignar este valor e igualmente el controlador se vería en el tab bar.

Si vamos a SecondViewController.xib tampoco encontraremos ningún tab bar.

Hasta ahora hemos visto que solo hay dos view controllers que corresponden a los tabs del tab bar. Pero entonces, ¿Dónde esta el tab bar?.

Abramos AppDelegate.m. Como podemos ver todo el código que instancia el tab bar está en el método application:didFinishLaunchingWithOptions.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // 1
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    // 2
    UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
    UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    
    //3
    self.tabBarController = [[UITabBarController alloc] init];
    
    //4
    self.tabBarController.viewControllers = @[viewController1, viewController2];
    
    //5
    self.window.rootViewController = self.tabBarController;
    
    //6
    [self.window makeKeyAndVisible];
    
    return YES;
}

Veamos que está pasando:

  1. Alocamos la ventana;
  2. Instanciamos los dos view controlles que vamos a mostrar en el tab bar;
  3. Instanciamos el tab bar controller;
  4. Asignamos los dos view controllers;
  5. Asignamos el tab bar como vista raiz de la ventana;
  6. Y la hacemos visible.

Agregando otro tab al tab bar

Ahora que ya entendemos como funciona la lógica de la aplicación que tenemos, vamos a crear otro controlador para agregarlo como una tercera pestaña del tabbar.

En Xcode vamos a File -> New -> File…

Seleccionamos Objective-C Class en la división de iOS.

Le ponemos un nombre a nuestra clase. En mi caso será ThirdViewController y heredará de UIViewController.

Ahora vayamos a ThridViewController.xib y manipulemos un poco nuestra vista. Agreguemos un label que diga “Third View” para saber que es la tercera vista y si queremos podemos colocar el bottom bar como lo tienen los otros view controllers que generó Xcode, nuevamente esto es opcional.

Para agregarlo como un tercer tab, simplente tenemos que ir a AppDelegate.m e importar ThirdViewController.h:

#import "ThirdViewController.h"

Instanciar el view controller en application:didFinishLaunchingWithOptions:

UIViewController *viewController3 = [[ThirdViewController alloc] initWithNibName:@"ThirdViewController"
                                                                              bundle:nil];

Y asignarlo al tabbar:

self.tabBarController.viewControllers = @[viewController1,
                                              viewController2,
                                              viewController3];

El método ahora debe lucir de la siguiente manera:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:@"FirstViewController"
                                                                              bundle:nil];
    UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:@"SecondViewController"
                                                                               bundle:nil];
    UIViewController *viewController3 = [[ThirdViewController alloc] initWithNibName:@"ThirdViewController"
                                                                              bundle:nil];

    self.tabBarController = [[UITabBarController alloc] init];
    self.tabBarController.viewControllers = @[viewController1,
                                              viewController2,
                                              viewController3];
    
    self.window.rootViewController = self.tabBarController;
    [self.window makeKeyAndVisible];
    
    return YES;
}

Si corremos la aplicación vemos que el view controller aparece como una tercera vista, pero aún no tiene ninguna imagen ni texto en el botón


Asignando imagen y texto al tercer tab

Si vamos a la implementación de FirstViewController y SecondViewController, vemos que el método initWithNibName:bundle asigna un titulo con un localizedString (estos se usan usar traducciones, pero en este ejemplo podría utilizar un simple NSString) y una imagen:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"First", @"First");
        self.tabBarItem.image = [UIImage imageNamed:@"first"];
    }
    return self;
}

Para el caso de ThirdViewController no vamos a hacerlo de esta manera porque quiero enseñarles como utilizar los botones que vienen integrados con el framework.

Abrimos ThirdViewController.m y nos vamos al método initWithNibName:bundle y dentro del if colocamos:

self.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemFavorites
                                                             tag:99];

Analicemos esta línea de código.

En la parte initWithTabBarSystemItem: pasamos como parámetro UITabBarSystemItemFavorites, este valor hace que se muestre la imagen de la estrella con el título “Favorites”. Este valor es parte de un enum que contiene otros valores como:

UITabBarSystemItemMore
UITabBarSystemItemFavorites
UITabBarSystemItemFeatured
UITabBarSystemItemTopRated
UITabBarSystemItemRecents
UITabBarSystemItemContacts
UITabBarSystemItemHistory
UITabBarSystemItemBookmarks
UITabBarSystemItemSearch
UITabBarSystemItemDownloads
UITabBarSystemItemMostRecent
UITabBarSystemItemMostViewed

En la parte tag: podemos asignar cualquier valor, esto es simplemente un identificador. Yo usé 99.

Ahora, si corremos la app una vez más observaremos como ya el tercer tab tiene su imagen y título.


Conclusión

En este capítulo hemos aprendido a utilizar el UITabBarController, uno de los que generan más dudas en los aprendices de iOS.

Como siempre cualquier duda o comentario no dejen de publicarlo en su sección correspondiente más abajo.

¡Hasta la aproxima!.

Adios.