iOS desde Cero: Storyboards

Publicado el 12 agosto 2013 por Codehero @codeheroblog

Los storyboards son una de las características más emocionantes del iOS SDK. Hoy esteremos dándole un vistazo a esta funcionalidad en iOS desde Cero.

En esencia, los Storyboards son un nuevo tipo de contenedor disponible en Xcode para mantener colecciones de xib’s (nibs). Como resultado, puede que nunca necesites utilizar un archivo xib independiente de nuevo. Un Storyboard no sólo contiene una colección de xib’s, sino que también permite controlar visualmente cómo estos transicionan entre sí. Esto significa que todo el flujo de la interfaz de la aplicación se puede modelar y visualizar a través de un único archivo. Generalmente, el flujo de interfaz requiere de la capacidad de obtener instancias de controladores a los que desea avanzar, enviar datos a dichas instancias, e incluso mostrarlas mediante alguna transición.


Creando un nuevo proyecto

Creamos un nuevo proyecto de tipo “Single View Application”.

Le colocamos un nombre a nuestro proyecto y habilitamos el check que dice “Use Storyboards”.


Creando escenas

Todas las vistas que arrastremos a un Storyboard se les llama escenas. Algunas de estas pueden tener archivos .h y .m, otras pueden ser completamente configuradas por Interface Builder.

Agreguemos un Table View Controller a nuestro storyboard.

Habiendo seleccionado el tableview en el inspector podemos convertirlo en un tableview estático, esto quiere decir que su contenido puede ser modelador en Interface Builder.

Si hacemos click en una de las celdas que viene por defecto en el controlador podemos colocarle un estilo. Yo le colocaré estilo Basic:

Y colocarle como identificador “myCell”.

Ahora podemos hacer doble click sobre la celda y editar el texto del label que contiene.

Agreguemos un botón en el primer view controller.

Ahora agreguemos un tercer view controller con un label:


Creando transiciones

Las transiciones se logran haciendo segues. Los segues conectan escenas.

Vamos a hacer ctrl + click sobre el botón del primer view controller y arrastrando hasta el table view controller creamos nuestro primer segue. Asegurate de hacer click en Push en el menú contextual que aparece.

Y ahora podemos observar como aparece una flecha entre los dos controladores. Esto significa que al hacer click sobre el botón, la app navegará hasta el table view cotroller.

Si corremos esta aplicación en este momento nos daremos cuenta que al hacer tap sobre el botón no nos va a llevar a ningún lado. Esto es porque la aplicación necesita de un Navigation controller para poder cambiar de una vista a otra. Esto lo logramos haciendo click en el primer view controller y haciendo click en Editor -> Product -> Embed In -> Navigation Controller envolvemos el primer view controller en un Navigation Controller.

Ahora si podemos correr el proyecto y ver como funciona la transición.


Pasando valores de una vista a otra

Usando segues se puede pasar pasar datos de una vista a otra fácilmente. Primero que nada necesitamos crear una clase y asignarla al tercer view controller que creamos (el que tiene el label).

Vamos a File -> New -> File…

Seleccionamos “Objective-C Class” y la guardamos asegurándonos de que sea una subclase de UIViewController. Yo la llamé LabelViewController.

Ahora volvemos al Storyboard y asignamos a LabelViewController como clase controlador de la escena. Esto lo hacemos haciendo click sobre el tercer view controller y asignándolo en el inspector de identidad.

Ahora creamos un outlet en el controlador para el label de la escena y un property string para guardar el valor que esta va a contener.

Después de esto nuestro código debería lucir de la siguiente manera:

@interface LabelViewController : UIViewController


@property (nonatomic, strong) NSString *labelValue;

@property (weak, nonatomic) IBOutlet UILabel *label;

@end

Ahora en la implementación de la clase asignamos el valor del labelValue a label cuando cargue la vista (recuerda que antes de que este evento se dispare los outlets no existen).

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [_label setText:_labelValue];
}

Ahora debemos crear otra clase para el table view controller, de modo que podamos pasar los datos de una a la otra. Repetimos el mismo procedimiento para crear una clase solo que ahora vamos a heredar de UITableViewController.

Asignamos la clase a la escena.

Conectamos con un segue las escenas.

Para pasar un valor de una vista a otra se debe sobre escribir el método prepareForSegue:sender: en el controlador de partida, por lo tanto en TableViewController debemos implementarlo. (recuerda importar labelViewController en TableViewController)

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    LabelViewController *nextViewController = [segue destinationViewController];
    nextViewController.labelValue = @"Hola desde el Table View";
}

Y debemos configurar nuestro table view.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"myCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                      reuseIdentifier:CellIdentifier];
    }
    
    return cell;
}

Ahora si corremos el proyecto y navegamos hasta el tercer view controller, podremos ver como el último view controller muestra un mensaje que dice “Hola desde el Table View” en un label.


Conclusión

Los Storyboards nos permiten ahorrarnos muchas lineas de código que antes teníamos que escribir obligatoriamente, pero su uso no permite crear views fuera de una escena, para esto se requeriría un archivo xib, ambos se complementan y ninguno reemplaza al otro.

Adios.