Bienvenido, les saluda Miguel y para hoy les traigo un tutorial.
Índice
Recuperar el control que pensaba que SwiftUI
sacrificó por simplicidad
SwiftUI optimiza muchas de las funcionalidades, capacidades y controles comunes en las aplicaciones.
Es bastante evidente que un enfoque durante el desarrollo fue considerar cómo los desarrolladores podrían incorporar elementos comunes de la interfaz de usuario de manera simple y con gran parte de la sobrecarga poderosamente automatizada.
El marco incluso tiene en cuenta la usabilidad y las perspectivas de diseño.
Esto es muy bienvenido por la comunidad de iOS, que ha tenido experiencia trabajando con Interface Builder
, Storyboards
y ViewControllers
.
Cualquiera que haya lidiado con la complejidad que exigen incluso las características más simples podría comprender los beneficios de SwiftUI
.
¿La captura?
A medida que los desarrolladores comienzan a crear aplicaciones cada vez más complejas con SwiftUI, hay ocasiones en las que parece que las funciones (como la navegación) son casi demasiado simplistas.
A medida que me desplazo por las preguntas y respuestas de Stack Overflow, veo un número creciente de problemas etiquetados que requieren más control de desarrollo. Del mismo modo, veo una serie de soluciones que implican envolver soluciones UIKit más antiguas para cubrir los vacíos.
Mi esperanza es que a medida que SwiftUI continúe madurando y desarrollándose, veremos cada vez menos UIKit y más SwiftUI (y ese definitivamente pareció ser el caso en la WWDC20
de este año).
Pero también tengo la esperanza de que solo recurramos a otro marco como último recurso. Tal vez podamos encontrar soluciones SwiftUI puras, como sugiere Apple, aunque puedan parecer de poca calidad y/o menos bonitas. Sin embargo, yo diría que estaríamos haciendo lo mismo al incorporar UIKit.
Para el registro: no tengo nada realmente en contra de UIKit, solo un deseo saludable de reducir la dependencia y ver que un nuevo marco se mantenga por sí solo.
¿SwiftUI Unwind
?
Una de esas habilidades que los desarrolladores parecen perder es relajarse. Obtenemos un botón de retroceso "gratis"
con Navigation
, pero no hay opción para agregarle ningún código o compleciones.
En los viejos tiempos de UIKit, había algunas opciones. Si hubiéramos estado usando un segue
, podríamos poner código en un desenrollado. La otra opción era usar viewWillDisapear
o algún otro evento del ciclo de vida.
"gratis"
es disparar .onDisappear
( listado como uno de los eventos del ciclo de vida de SwiftUI ).
Sin embargo, esto se está ejecutando técnicamente porque el padre ya está a la vista, lo que puede producir resultados de IU incómodos. Y dado que el padre en un NavigationView
ya está apareciendo, onAppear
no es una apuesta segura.
El otro enfoque, entonces, es tomar el asunto en nuestras propias manos y crear un botón de retroceso personalizado. Esto es natural porque, aunque no estamos usando el botón creado de forma gratuita, tenemos la capacidad de agregar elementos de barra a nuestra vista.
Si nuestra aplicación requiere algo más que simplemente navegar hacia atrás, deberíamos aprovechar absolutamente este enfoque.
Creando nuestro botón de retroceso
En realidad, es bastante simple crear un nuevo botón de retroceso, aunque es posible que se le presenten algunos modificadores nuevos y demás en el camino.
La suposición aquí es que usted tiene una vista de detalle que usted está usando un NavigationView
para navegar por la cadena a
y desea navegar copia de seguridad de la cadena de con un botón de retroceso.
Primero, donde normalmente declararía las propiedades de su vista, necesitará extraer una propiedad del entorno del sistema llamada presentationMode
:
@Environment (\. PresentationMode) var presentationMode
Desafortunadamente, los documentos de Apple parecen carecer de profundidad en cuanto a presentationMode
(para la propiedad de la instancia y menos aún para la estructura ).
Lo que sí sabemos es que es una propiedad predeterminada para todas las vistas que se vincula al entorno de su aplicación. Esto será esencial en solo un minuto.
Las vistas incluyen modificadores para interactuar con la navegación en caso de que formen parte de una jerarquía de navegación.
En nuestro caso, queremos agregar algunos modificadores a la capa superior de nuestra vista de detalle (por ejemplo, la pila que lo abarca).
El primer modificador ocultará el botón de retroceso predeterminado:
.navigationBarBackButtonHidden(true)
El segundo modificador que necesitaremos nos permitirá agregar elementos a la barra de navegación (el espacio reservado en la parte superior de una vista descendiente de navegación):
.navigationBarItems(leading: <View(s)>)
Para nuestros propósitos, crearemos un botón como este:
¡Eso es! Ahora tenemos nuestro botón de retroceso capaz de ejecutar código antes de que descartemos la vista.
Escenarios de copia de seguridad
¿Por qué alguien querría un botón de retroceso personalizado? Se puede argumentar que la mayoría de los escenarios podrían cubrirse usando lo que ya está disponible, especialmente usando Bindings y Combine. Aquí hay algunos escenarios en los que creo que podría ser útil.
Un posible escenario para necesitar un botón de retroceso personalizado es querer realizar una acción en la vista actual antes de navegar. Uno de esos casos es preguntar al usuario si está seguro de que quiere navegar hacia atrás (ejemplo innovador, lo sé).
En este caso, podemos agregar una alerta a nuestra vista que le pregunte al usuario si está seguro de que desea navegar hacia atrás. También moveremos el dismiss
llame desde nuestro botón de retroceso y en la alerta afirmativa:
Por último, queremos activar la alerta a través del botón Atrás:
// Add a new State to your View @State var showAlert: Bool = false // Add the following trigger inside the Back button // A tener en cuenta: we set to true, not toggle self.showAlert = true
Si los datos se crean o editan en la pantalla, podría haber un escenario en el que no queremos necesariamente que esos cambios sean vinculables.
Quizás preferiríamos que el usuario continúe con su experiencia, y solo después de que haya indicado que ha terminado presionando el botón Atrás, comenzamos a almacenar / sincronizar los datos. Incluso masajee los datos antes de hacerlo.
Es de suponer que los datos ya estarían disponibles en la vista actual. Es una cuestión de simplemente agregar el código necesario justo en el botón de retroceso antes de nuestro dismiss
.
¿Qué sucede si tenemos una vista en la que planeamos navegar de regreso a, pero desde, múltiples descendientes diferentes? Al volver a esa vista, queremos ejecutar algún tipo de proceso (y, como se indicó anteriormente, onAppear
no cuenta al regresar con el padre).
La solución, entonces, es pasar un cierre de devolución de llamada para que se ejecute en nuestro botón de retroceso.
Esto ciega al descendiente de la complejidad de cualquier cosa que deba hacerse y simplemente lo convierte en el mensajero y disparador.
Una forma de aceptar y ejecutar un cierre es la siguiente:
// Make a closure an optional parameter in the descendant View var onBack: (() -> Void)? = nil // In our Back button, we'll run the closure, provided it's not nil onBack?()
Recuperar el control
Amo SwiftUI, más aún después de la WWDC20
de este año. Si bien aún queda algo de madurez por venir, no significa que no podamos escribir aplicaciones completamente sólidas y potentes. Por el contrario, espero ver algunas aplicaciones geniales escritas en SwiftUI.
Solo recuerde que aunque SwiftUI toma gran parte de la holgura y simplifica las cosas, eso no significa que no podamos obtener el acceso y el control que necesitamos para crear aplicaciones increíbles.
¡Excava y recupera el control que crees que has perdido!
Añadir comentario