Navegación en UIKit: UINavigationController Push
La navegación Push es muy útil y muy usada en iOS. Para hacerla necesitamos un UINavigationController y ir pusheando ViewControllers, de esta manera podremos ir añadiendo ViewControllers a nuestra jerarquía de vistas. Hoy aprendemos a cómo usar esta navegación que te servirá para crear tus apps.
Tabla de contenido
Hoy en SwiftBeta vamos a ver otra manera para poder navegar de un View Controller a otro. Dentro de iOS es muy común la navegación push, esta consiste en navegar de un ViewController a otro como el gif que muestro acontinuación.
Este tipo de navegación lo vemos en aplicaciones del propio sistema operativo. En el anterior posts vimos a cómo presentar un ViewController usando modales, básicamente es presentar un ViewController dentro de otro, pero hoy vamos a ver un nuevo Controller llamado UINavigationController. Este NavigationController va a ser la base de nuestra navegación, y lo que haremos será llamar a este controller para poder pushear ViewControllers en la jerarquía de vistas. Solo vamos a tener un UINavigationController, y en lugar de decirle al ViewController que presente otro ViewController, esta tarea se la vamos a delegar al UINavigationController. Y lo que hará el NaviegationController es ir añadiendo ViewControllers a nuestra jerarquía de vistas, será como un Stack. No te preocupes que es super sencillo y lo ¡vamos a verlo paso a paso!
Creamos el proyecto en Xcode
Lo primero de todo que vamos hacer es crear el proyecto en Xcode. Acuérdate que estamos usando UIKit, es por eso que debes seleccionar Storyboard en Interface.
Una vez hemos creado el proyecto nos vamos al Storyboard. Allí vamos a añadir un NavigationController a nuestro ViewController. Para hacerlo seleccionamos el ViewController y nos vamos al menu, allí seleccionamos Editor -> Embed in -> NavigationController
Fíjate que se ha añadido una nueva vista a tu Storyboard, esta vista es el UINavigationController
Lo siguiente que vamos hacer es renombrar ViewController a ViewControllerA, y para ello debemos modificar nuestro ViewController dentro del Storyboard y también renombrar la clase ViewController a ViewControllerA:
Lo siguiente que vamos hacer es:
- Añadir un title a nuestro ViewController, al añadir un título aparecerá en el NavigationController
- Añadir un UIBarButtonItem a nuestro UINavigationController. Al pulsar este nuevo Button le diremos al UINavigationController que haga push de un nuevo UIViewController.
Ahora debemos crear un nuevo ViewController, lo vamos a llamar ViewControllerB
Una vez creado ViewControllerB, volvemos a ViewControllerA y rellenamos el método nextViewController:
Si compilamos podemos ver que:
- Al pulsar el button Next, se pushea el ViewControllerB
- Al presentarse ViewControllerB aparece un button en la parte izquierda del UINavigationController, si lo pulsamos volvemos al ViewControllerA
- Desde ViewControllerB, tenemos el efecto de arrastrar y ver la transición de cómo volvemos a ViewControllerA (esto viene completamente gratis al hacer push de un ViewController desde un UINavigationController).
Lo siguiente que vamos hacer es crear un ViewControllerC, y desde allí vamos a presentar ViewControllerD, utilizaremos lo que aprendimos en el anterior post de presentar modales.
De momento, nuestro ViewControllerC va a tener el siguiente código:
Una vez creado volvemos a ViewControllerB para que cuando el user pulse el Button del NavigationBar, se muestra el ViewControllerC
Compilamos y probamos que todo funciona bien. Una vez comprobado, vamos a añadir un UIButton a nuestro ViewControllerC, al apretar este UIButton se mostrará el ViewControllerD (que aún no hemos creado, lo haremos cuando añadamos el UIButton a ViewControllerC).
Al añadir el siguiente código, tendremos un error. Se queja que no hemos creado ViewControllerD y por lo tanto no sabe como crear una instancia. Así que, vamos a crearlo (no nos vamos a complicar y va a ser muy sencillo):
Si compilamos, vamos a ver la navegación que hemos creado. Podemos pushear 2 View Controllers. De A pusheamos B, y de B pusheamos C, y una vez que estamos en C presentamos el modal D. Nosotros aquí ahora podríamos rellenar las vistas del ViewController con las subvistas que quisieramos: UIButtons, UILabel, UITableView, UICollectionView, etc.
Hemos visto cómo pushear un ViewController dentro de un UINavigationController, pero también podemos hacer pop. Esto es muy parecido a present y dismiss de los modales.
Pop ViewController
Imagina que en tu UINavigationController has hecho push de varios ViewControllers, en lugar de ir pulsando el button de back para volver a la pantalla inicial, lo que se puede hacer es usar el método popToRootViewController(animated:) este método sirve para volver al root view controller de tu jerarquía de vistas. Vamos a probarlo con el código que hemos creado. Nos vamos al ViewControllerC y en lugar de que al pulsar el Button aparezca el modal del ViewControllerD, lo que vamos hacer es que navegue directamente a ViewControllerA, y para hacerlo solo necesitmos una línea de código:
func startNavigation() {
// self.present(ViewControllerD(), animated: true)
self.navigationController?.popToRootViewController(animated: true)
}
Si compilamos, y navegamos hasta ViewControllerC, al apretar el UIButton volvemos automáticamente hasta ViewControllerA, ¡sin pasar por ViewControllerB! esto es muy útil para romper flows de navegación. También, otro detalle curioso es que en lugar de que el user pulsara el Button back que se crea automatícamente al añadir un UINavigationController, podríamos añadir la acción del back en cualquier otro button de nuestra vista. Vamos a volver modificar el método de starNavigation() y vamos a simular el código que realiza el button back.
func startNavigation() {
// self.present(ViewControllerD(), animated: true)
self.navigationController?.popViewController(animated: true)
}
Si lo probamos, vemos cómo al apretar el UIButton volvemos al ViewController anterior. ¿Sencillo verdad? cuando programamos esta navegación es muy simple customizar las acciones que queremos realizar.
Conclusión
Hoy hemos aprendido otra manera de tener una navegación dentro de nuestra aplicación iOS. En lugar de presentar desde un UIViewController, lo que hacemos es presentar ViewControllers desde un componente nuevo llamado UINavigationController. Esta manera de presentar ViewControllers es muy común dentro de iOS.