iOS desde Cero: Navigation Controller
Como vimos en el capítulo anterior los table views son una excelente manera de desplegar data tabular. Ahora, en este nuevo capitulo vamos a hablar de como navegar de una vista a otra utilizando un navigation controller.
Un nuevo proyecto
Vamos a crear un nuevo proyecto en Xcode para esta demostración.
Abrimos Xcode y hacemes click en File -> New -> Project…
Seleccionamos Application en la sección de iOS y hacemos doble click en Empty Application.
Le damos un nombre a nuestro proyecto, seleccionamos arc (automatic reference counting) y guardamos. Ya en esto deberíamos ser unos expertos.
En este proyecto hemos creado una nueva aplicación vacía. Si la corremos veremos que solo se muestra una pantalla en blanco.
Ahora, los próximos objetivos para completar esta demostración son: instanciar y asignar el primer view controller a la ventana, luego crear otro view controller, y navegar hasta él pasándole un parámetro desde el view controller anterior.
Creando el primer View Controller
Vamos a File -> New -> File…, y le hacemos click a Cocoa Touch en el menú iOS y seleccionamos Objective-C Class.
Ahora le damos un nombre a nuestra clases, le decimos que hereda de UIViewController y le decimos que lo queremos con un Xib para interfaz de usuario. Yo lo voy a llamar MainViewController.
Ahora vamos MainViewController.xib y arrastramos un botón a la vista. Yo le escribí de titulo “Ir a la próxima vista”. Este botón al hacerle click nos va a llevar a la próxima vista. Pero primero hay que escribir el código que haga esta magia.
En la vista del asistente, de modo que tengamos el editor de vistas y de código lado a lado (asegurare que el editor de código esté en en archivo MainViewController.h), sosteniendo la tecla control hacemos click sobre el botón y arrastramos hasta el código.
Creamos una acción. Yo la llamé goToTheNextView y nos aseguramos que esté seleccionado “Touch Up Inside”. Este es el método que se va a llamar al presionar el botón.
Ahora antes de navegar al segundo view controller tenemos que crearlo.
Creando el segundo View Controller
Vamos nuevamente a File -> New -> File… y creamos otro view controller. En este caso yo lo llamé NextViewController.
Abrimos NextViewController.xib y le agregamos un label a la vista. En esta vamos a mostrar un mensaje enviado desde la vista anterior, pero ya llegaremos a eso, por ahora vamos a conectar el label con el código mediante un outlet como lo hicimos con el botón.
Le colocamos un nombre, yo lo llamé “label”.
De vuelta al primer view controller
Ya que creamos el segundo view controller podemos volver al primero para escribir el código que nos va a llevar hasta el segundo.
Abrimos MainViewController.m e importamos el segundo view controller en el primero antes de la implementación:
#import "NextViewController.h"
Ahora vamos al método de la acción del botón que creamos, goToNextView: y escribimos:
- (IBAction)goToNextView:(UIButton *)sender { NextViewController *nextView = [[NextViewController alloc] initWithNibName:nil bundle:nil]; // 1 [self.navigationController pushViewController:nextView animated:YES]; // 2 }
- Creamos uns instancia de NextViewController llamada nextView. Con indicarle initWithNibName:nil bundle:nil el objeto asume que el xib se llama igual que la clase.
- Todos los UIViewController tienen una propiedad llamada navigationController. Esta es una referencia al navigation controller que permite la navegación de una vista a otra, ya hablaremos de esto con mayor detalle. Aquí le decimos a este navigation controller que navegue a nextView y que lo haga con animación.
Si corremos la aplicación en este momento seguiremos viendo la misma pantalla blanca que teníamos al comienzo. Esto es porque aún no hemos dicho a la aplicación con que vista empezar.
Creando el Navigation Controller
Abrimos AppDelegate.m y vamos al método application:didFinishLaunchingWithOptions:. Cuando abrimos la aplicación por primera vez, este método es llamado. Aquí es donde debemos crear nuestro navigation controller y decirle a la app que inicie con MainViewController.
Primero importamos MainViewController:
#import "MainViewController.h"
Inicialmente application:didFinishLaunchingWithOptions: debería lucir así:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; }
Nosotros vamos a modificarlo para que luzca así:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // 1 MainViewController *mainView = [[MainViewController alloc] initWithNibName:nil bundle:nil]; // 2 UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:mainView]; // 3 [self.window setRootViewController:navigationController]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; }
- Creamos una instancia de MainViewController llamada mainView.
- Creamos una instancia de un navigation controller y le decimos que inicie con mainView como vista inicial. Desde este momento a la propiedad navigationController de mainView se le asigna automáticamente este navigation controller, así es como luego podemos llamarlo desde la acción del botón de MainViewController.
- Y le decimos a la ventana que inicie con el navigation controller. Todas las aplicaciones deberían tener una sola ventana. Las ventanas solo pueden cargar un solo view controller.
Ahora si corremos la app, podemos ver que aparece MainViewController y si le damos al botón navegamos a NextViewController.
¿Como funciona?
Los navigation controller no son visibles. UINavigationController es un controlador que maneja una lista de view controlers y permite la navegación de uno hasta otro. La barra azul de arriba viene con el navigation controller, podemos hacerla invisible si queremos.
El botón de “volver” que aparece cuando navegamos a la segunda vista lo coloca automáticamente el navigation controller, no tenemos que hacer nada para que aparezca.
Cuando llamamos a pushViewController:animated en MainViewController le estamos agregando al navigation controller un nuevo view controller a su lista interna y trasicionamos de una vista a otra.
Pasando objetos / parámetros de una vista a otra
Vamos a NextViewController.h y agregamos una propiedad que retenga el texto que vamos a asignar al label:
@property (nonatomic, strong) NSString *text;
Ahora en NextViewController.m ubicamos viewDidLoad y asignamos el texto al label:
- (void)viewDidLoad { [super viewDidLoad]; [_label setText:_text]; }
Volvemos a MainViewController.m y nos posicionamos sobre el método que se dispara cuando se presiona el botón, goToNextView:, y le agregamos el siguiente código antes de hacer “push” a la siguiente vista.
[nextView setText:@"Hola desde la vista anterior"];
Mediante propiedades o métodos podemos pasar objetos o parámetros de una clase a otra. En este caso estoy asignando el valor del label de NextViewController desde MainViewController. goToNextView: debería lucir así ahora:
- (IBAction)goToNextView:(UIButton *)sender { NextViewController *nextView = [[NextViewController alloc] initWithNibName:nil bundle:nil]; [nextView setText:@"Hola desde la vista anterior"]; [self.navigationController pushViewController:nextView animated:YES]; }
¿Por qué no asignar el texto directamente al label?. Porque los outlets no se inicializan antes de ViewDidLoad ser llamado. ViewDidLoad es llamado luego de que la vista carga, y la vista carga cuando la app va a mostrarla por pantalla, por lo tanto cuando la asignamos por código antes de esta ser mostrada, el label aun no existe, por eso debemos pasar el texto primero y luego este es asignado al label.
Ahora si corremos la aplicación veremos como el label de la segunda vista muestra el mensaje enviado desde la primera.
Conclusión
En este capitulo aprendimos a utilizar el navigation controller, uno de los controladores mas importantes de iOS, pero no solo eso, aprendimos a hacer una aplicación vacía también, donde tuvimos que asignar manualmente la primera vista de la aplicación.
Espero que haya quedado todo claro y que estés de acuerdo conmigo en que los navigation controllers no son tan complicados.
Cualquier duda házmela saber en los comentarios. Ya será hasta el próximo capítulo.
Adios.