Blog

SwiftUI: Introducción e ideas a tener en cuenta

Contenidos

¿Has oído hablar ya de SwiftUI? SwiftUI es el nuevo framework de usuario declarativo que Apple está defendiendo como el futuro del desarrollo frontend de iOS. Aunque sólo tiene dos años, SwiftUI es un framework robusto listo para el consumo. Aquí hay una breve introducción al frameowkr y algunas peculiaridades a tener en cuenta al considerar el cambio de UIKit a SwiftUI en tu próximo proyecto de iOS.

State y nuevos Property Wrappers

La verdadera belleza de SwiftUI viene de su simplificación del patrón arquitectónico de la vista. La arquitectura de UIKit comúnmente requiere tres partes para lograr el ciclo de vida de la vista: ViewModel, ViewController, View. El ViewModel le dice al ViewController cómo son los datos. El ViewController aplica el ViewModel a la Vista. El ViewController maneja la interacción del usuario en la Vista y modifica el ViewModel según sea necesario. Y el ciclo se repite de nuevo. SwiftUI elimina el intermediario ViewController y deja a la Vista a cargo de manejar los cambios del ViewModel. ¿Cómo consigue SwiftUI esto? Nuevos Property Wrappers. La gestión de estados con Property Wrappers cumple con la responsabilidad de conectar los modelos de datos a los elementos de la vista utilizables.

@State

@State demuestra el verdadero poder de SwiftUI en dar a cada vista la capacidad de gestionar su propio estado. Las propiedades @State son privadas por convención, ya que gestionan los cambios de estado en una única vista. Cada vez que una propiedad @State cambia de valor, todos los elementos de la vista (por ejemplo, texto, botón, imagen, etc.) que hacen referencia a esa propiedad se vuelven a procesar.

@Binding

Otro principio rector de SwiftUI es tener una única fuente de verdad. Imagina un escenario en el que tienes una vista padre que rastrea una propiedad usando @State y tiene una vista hija que necesita acceder a la misma propiedad. Podrías duplicar la propiedad y tener una variable @State en ambas vistas para realizar el seguimiento. Sin embargo, esto se vuelve bastante complicado cuando se necesita actualizar los cambios de la propiedad en dos lugares diferentes. Aquí es donde entran los enlaces. Los enlaces conectan la propiedad @State en la vista principal con la propiedad @Binding en la vista secundaria a través de un enlace (sintaxis «$»). Cualquier cambio en la propiedad se refleja tanto en la vista padre como en la vista hija.

@ObservedObject + @Published

@State se utiliza normalmente para gestionar el estado de las propiedades de los tipos incorporados (es decir, String, Int, Bool, etc.). Sin embargo, un caso de uso común sería el seguimiento del estado de una variable de un tipo personalizado. Utiliza @ObservedObject para declarar una variable de estado de tipo personalizado en una Vista y utiliza @Published en las propiedades del tipo personalizado que deben desencadenar una actualización de la Vista cuando sus valores cambien.

@EnvironmentObject

A veces hay escenarios en los que ciertas Vistas necesitan acceder a una propiedad particular que otras Vistas no tienen en cuenta. Imagina que tanto la Vista raíz de una aplicación como alguna Vista hija lejana en la jerarquía de Vistas necesitan acceder a la misma propiedad. Una solución es gestionar la propiedad @State en la vista raíz y pasar el valor de la propiedad mediante bindings a través de cada vista hija hasta llegar a la vista deseada. Esto parece un desperdicio, ya que ninguna de las vistas intermedias tiene acceso a la propiedad. En su lugar, utiliza la envoltura @EnvironmentObject para permitir que todos los descendientes de una vista accedan a la propiedad sin el uso de enlaces.

El orden importa con los modificadores de vista

Un modificador de vista es un método en una vista que realiza un cambio de estilo en esa vista y devuelve una versión modificada de la misma. Los modificadores pueden encadenarse para alterar rápidamente el color, el tamaño, la forma, la posición, etc. de una vista. Es importante entender que cada modificador devuelve una nueva versión de la vista y no la vista original sin modificar (similar al patrón de diseño del constructor). Esto significa que cada modificador encadenado sucesivamente está interactuando esencialmente con una vista diferente.

Si aplicamos los mismos cuatro modificadores a la misma imagen pero obtenemos resultados diferentes. ¿A qué se debe esto? La respuesta: el orden de los modificadores es importante. Supongamos dos ejemplos en los que aplicamos cuatro modificadores y donde la única diferencia entre los dos ejemplos es que aplicamos el modificador .cornerRadius(20) antes del modificador .padding() en el primer ejemplo. ¿Por qué es importante? Como se ha mencionado, los modificadores devuelven una nueva versión de la Vista cada vez. En el primer ejemplo, cuando llamamos a .cornerRadius(20) se nos devuelve una Vista con esquinas de radio 20. Cuando llamamos a .padding() añadimos un relleno estándar a la nueva Vista que ya tiene un radio de esquina. En el segundo ejemplo, añadimos primero el relleno estándar con .padding() y luego añadimos un radio de esquina con .cornerRadius(20) en la nueva Vista. Como la imagen ya tiene relleno cuando se aplica el radio de esquina, los cambios de radio se producen en el relleno invisible y no son visibles en la Vista.

Identificador de etiqueta única NavigationLink

Respecto a a navegación, una forma alternativa de inicializar un NaviationLink es proporcionando también una selección y una etiqueta:

Esto es comúnmente usado cuando se itera sobre un array y se crea una colección de elementos de Vista para cada miembro del arreglo. Cada elemento del array se convierte en un NavigationLink y cada NavigationLink recibe una etiqueta como identificador. Cada vez que se cambia el valor de la selección, se ejecuta el NavigationLink con la etiqueta correspondiente y se navega a su vista de destino. Cada NavigationLink debe tener una etiqueta única y consistente (no cambia). El incumplimiento de esta convención no da lugar a un error de compilación o de ejecución, pero crea frustrantes consecuencias no deseadas, como la invalidación de la navegación y la aparición de la vista de destino sólo durante una fracción de segundo. Para evitar este problema, asegúrate de utilizar librerías como UUID() (que garantizan identificadores únicos) cuando establezcas valores de ID en tus ViewModels.

SwiftUI es una poderosa herramienta que pretende simplificar el proceso de desarrollo de la interfaz de usuario de iOS. Si puedes dominar las diferencias de UIKit, SwiftUI es más que una herramienta viable para utilizar en aplicaciones de producción. Al igual que Swift ha tomado el relevo de Objective-C como el principal lenguaje de desarrollo de iOS, SwiftUI parece una apuesta segura para tomar el relevo de UIKit como el principal marco de interfaz de usuario en un futuro próximo.

Artículos destacados

Artículo

From offline to online.

Comparte tus ideas con nosotros