# Controladores contenedores

A diferencia de los otros tipos de *controllers* que hemos visto, los controladores contenedores no muestran directamente el contenido “principal” de la aplicación. El papel de estos controladores es, como su propio nombre indica, el de servir de contenedores a los controladores que muestran el contenido y permitir la navegación sencilla entre ellos.

En esta parte básica de la asignatura vamos a ver los dos controladores contenedores más típicos: el *tab bar* y el *navigation*.

## Tab bar controllers

Permiten diseñar la típica aplicación dividida por “apartados” o “tabs”. Por ejemplo lo podemos ver en la aplicación de “salud” de iOS 8 (entre muchísimas otras)

![](/files/-LDGNZaPBqJs0rA-FdrN)

Lo que tenemos es un controlador de tipo “tab bar” que gestiona la barra inferior y la navegación entre pantallas cuando pulsamos cada uno de sus iconos, pero el contenido de las pantallas lo gestionan los otros controladores. Podemos ver la estructura de forma más clara si arrastramos un *tab bar controller* al *storyboard* desde la *object library*.

![](/files/-LDGNZaSImBq8nodO6nX)

Vemos que el nuevo *tab bar controller* aparece conectado a dos controladores convencionales (de la clase `UIViewController`). Automáticamente cuando pulsemos en cada icono, se saltará al controller asociado.

Podemos añadir pantallas a este *tab bar controller* sin más que crearlas en el *storyboard* y luego conectarlas. Hacemos `Ctrl+arrastrar` desde el *tab bar controller* hasta la pantalla a conectar y en el menú contextual elegimos el tipo de *segue* llamado `view controllers`.

Otra forma de crear un *tab bar controller* relacionado con una pantalla que ya tengamos creada es seleccionar la misma y en el menú de `Editor` elegir `Embed in > Tab bar controller`. Aparecerá un tab bar controller con un único icono en la barra inferior, y ya conectado a la pantalla actual.

## Personalizar la barra inferior

Desde el *interface builder* podemos cambiar algunas propiedades básicas de los iconos de la barra inferior en el `attribute inspector`, como el icono, el título, la posición del título con respecto al icono, si queremos que aparezca un *badge*, etc.

> Si elegimos uno de los iconos del sistema no podremos cambiar el título ya que Apple considera que lo contrario podría inducir a confusión al usuario

Si queremos personalizar el icono poniendo nuestra propia imagen hay que tener en cuenta que los iconos de un *tab bar* son monocromáticos. El formato a usar es .png, del que el sistema examinará el canal alfa o de transparencia. Tomará como forma del icono los pixels que sean opacos ignorando su color. Podéis consultar más detalles sobre el formato y el tamaño recomendado en el apartado “[Bar button icons](https://developer.apple.com/library/ios/documentation/userexperience/conceptual/MobileHIG/BarIcons.html#//apple_ref/doc/uid/TP40006556-CH21-SW1)” de las [*iOS Human Interface Guidelines* ](https://developer.apple.com/library/ios/documentation/userexperience/conceptual/mobilehig/) de Apple.

## Navigation controllers

Los *navigation controller* sirven para crear estructuras de navegación jerárquica en las que tenemos pantallas y “subpantallas”. Estando en una de ellas podemos volver atrás una a una. El *navigation controller* se encargará de que se vaya cambiando automáticamente al controlador apropiado (el de la pantalla actual).

Nótese que cuando estamos navegando de este modo estamos usando una **pila de controladores**, en el sentido que tiene este término en estructuras de datos, ya que conforme vamos profundizando en la jerarquía se van apilando los controladores, y cuando volvemos atrás quitamos el de la parte de arriba de la pila.

## Crear un controlador de navegación

Hay dos formas de crear gráficamente un controlador de navegación:

1\) Seleccionamos un *controller* en el *storyboard* y elegimos la opción de menú de `Editor > Embed in > Navigation controller`. Se creará un controlador de navegación que tiene como controlador de contenido asociado al que habíamos seleccionado.

Nótese que como en el caso de los *tab bar controller* en el de navegación la pantalla está en gris indicando que el contenido no es responsabilidad de este controlador. En el controlador de contenido asociado podemos ver que la parte superior aparece en gris, indicando que esta es la *barra de navegación* que gestionará el controlador de navegación.

2\) Podemos arrastrar un `Navigation controller` desde la librería de objectos hasta el *storyboard*. Por defecto nos creará el controlador de navegación junto con un controlador de tabla, estructura apropiada para comenzar con una vista maestro/detalle. No obstante si no queremos este segundo controlador podemos borrarlo y conectar el de navegación con uno nuevo con `Ctrl+Arrastrar` entre ambos y seleccionando en el menú contextual la opción de `root view controller` bajo `relationship segue`.

### Añadir pantallas a la jerarquía

Para añadir un controlador a la jerarquía de navegación basta con `Ctrl+Arrastrar` entre el componente que dispararía el salto y el controlador de destino. En el menú contextual hay que elegir el *segue* de tipo *push*. Evidentemente el controlador de origen tiene que estar ya en la jerarquía de navegación para que esta operación funcione.

## Personalizar la barra de navegación

Automáticamente el controlador de navegación gestionará una barra de navegación en la parte superior de la pantalla. Esta barra muestra por defecto en su parte izquierda un botón `< Back` para ir al controlador anterior.

La barra de navegación es totalmente personalizable. Lo más inmediato es mostrar un título para la pantalla actual cambiando la propiedad `title` del controlador. Podemos hacerlo por ejemplo en el método `viewWillAppear` del mismo, ya que se ejecutará antes de mostrar la vista. Al cambiar el título del controlador también cambiará automáticamente el botón \`\`< Back\`\`\` para reflejar el nuevo título.

> Si el título del *controller* es demasiado largo y no cabe en el botón este seguirá con el título por defecto (`Back`)

Podemos cambiar completamente la barra de navegación. Es accesible mediante la propiedad `navigationItem` del controlador, y podemos cambiar por ejemplo:

* `backBarButtonItem`: el botón, de tipo `UIBarButtonItem`, que se utilizará para volver atrás a este controlador
* `titleView`: el componente con el título para el controlador, cuyo texto como hemos visto podemos cambiar con la propiedad `title` del controlador.
* `rightBarButtonItem`: por defecto `nil`. Típicamente se usa para añadir un botón para editar el contenido de la pantalla actual, pero podemos colocar lo que queramos.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mastermoviles.gitbook.io/interfaz-de-usuario-basico-en-ios/controladores-contenedores.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
