VIP+ SwiftUI + UIKit
SwiftUI interactúa y funciona perfectamente con el framework UIKit dentro de nuestras apps creadas desde su origen con SwiftUI, es posible colocar vistas UIKit y UIViewController’s dentro de vistas de SwiftUI y viceversa.
Me gustaría compartir como nuestro famoso UIPageViewController lo podemos integrar en una Vista SwiftUI y entenderlo como un componente más de nuestro diseño dentro de la App que podemos reutilizar cuantas veces necesitemos, y sabemos de sobra que los carruseles de imágenes estan siempre dentro de nuestro diseño, no obstante sabemos que podemos hacerlo directamente en SwiftUI y podriamos pasar de UIkit, pero aqui veremos consas muy interesantes.
Conoceremos algo nuevo el Coordinator, y para ello lo primero que vamos a tener en cuenta dentro de nuestra receta final son una serie de ingredientes que son fundamentales:
Proyecto vacío creado con SwiftUI
Esta parte es fácil ya tenemos el primer ingrediente vamos a por lo siguiente
Creación de componente UIPageViewController
Creamos una View que represente una UIPageViewController de UIKit, para ellos debemos tener en cuenta ajustar unos protocolos y los tipos personalizados que crean y configuran lo que UIkit necesita, mientras que SwiftUI se va a encargar del ciclo de vida y de la actualización cunado sea necesario, pues vamos al ello.
Nos creamos una carpeta dentro del proyecto y le llamamos Components y dentro creamos un Swift file para darle caña.
Vemos con calma creamos nuestra struct PageViewController en donde el controlador almacena un array de Page que deben ser del tipo View. Estas son la páginas que usaremos para desplazarnos entre ellas, pero vemos algo que el UIViewControllerRepresentable y eso que es?? según la documentación de Apple es la forma en la que se debe invocar un UIViewController dentro dela interfaz de SwiftUI, con tener en cuenta este protocolo podemos tener procesos de creación y actualización paralelos al comportamiento de SwiftUI, es capza de informar al sistema automáticamente de los cambios que ocurren dentro del ViewController a otras partes de la interfaz de SwiftUI, y si necesitamos implementar una forma de coordinación entre vista de SwiftUI se implementa algi nuevo llamado Coordintor que nos ayudará a facilitar interacciones ademas de delegaro mensajes desde la ViewController a cualquier vista de SwiftUI.
Una vez que implementas el protocolo SwiftUI debe llamar al metodo
makeUIViewController(context:) -> some UIViewController {}
Y es aquí cuando ya está preparado SwiftUI para mostrar la vista y luego controlar el ciclo de vida del UIViewController, super fácil no??
luego usamos otro método
updateUIViewController(: context:)
Este controla la actualización del UIViewController dentro de SwiftUI, esto hace que sea muy eficiente iniciando el controladro 1 vez durante la vida útil del UIViewController y luego se actualiza de manera intependiente.
En este punto debemos implementar VIP con SwiftUI y para ellos creamos una serie clase que nos van a permitir hacer una llamada de red a los servicios de iTunes así que voy a mostrar la estructura del proyecto para hacernos una idea, no obstante el proyecto de muestra está ubicado aquí.
la secuencia de imágenes muestran las capas VIP implementado con SwiftUI, planteando Clean Architecture desde la capa mas alta a la mas baja.
Bien!! vamos a ahora a ver como el Coordinator de la UIPageViewController va a ayudarnos para actualizar los datos y luego mostarlos en la vista ContentView, tenemos que declarar de manera anidada dentro del PageViewController una class Coordinator e implementar dicha clase en PageViewController, éste se autocompleta si declaramos primero la class anidada y luego en el método makeCoordinator le permitira a SwiftUI llamar a éste método antes de crear el ViewController como tal, Podemos utilizar este coordinador para implementar patrones comunes de Cocoa, como delegados, fuentes de datos y responder a eventos de usuario mediante target-action.
Vamos a modificar un poco le código, Inicia una matriz de controladores en el coordinador utilizando el Array de Pages de vistas.
El coordinador es un buen lugar para almacenar estos controladores, porque el sistema los inicializa solo una vez y antes de que los necesits para actualizar el controlador de vista.
Vamos a ir agregando los Delegados que necesita el UIPageViewController y completamos con los metodos delegados
En esencia estos dos metodos nos permitirán avanzar o retroceder entre los ViewController’s, bien vamos a ajustar la vista para que veamos si tenemos éxito o no, yeah!!
Vamos revisar ahora las capas mas altas ya que hemos terminado, en nuestra clase ContentView ya habiendo declarado nuestro viewModel, vamos a comprobar si nuestro array de Movies esta o no vacío y de estar con datos invocamos nuestro componente PageView(pages) un poco de sugar y mapeamos a otro componente el visual que se encargará de mostrar los datos y cargar la imagen (no olvidéis tener en cuenta el ATS).
Este componente nos incova el PageViewController con el coordinator y todo lo que hemos escrito.
Este componente es el resultado final de la vista y un poco de estilo para ver nuestras Stack’s de SwiftUI, si ejecutamos la App podemos ver el siguiente resultado.
Con un desplazamiento en horizontal, hacia adelante y hacia atrás, pues ya está, super fácil.