@EnvirontmentObject en SWIFTUI en Español
EnvironmentObject es otro Property Wrapper en SwiftUI que usamos para proporcionar desde alguna vista padre una clase que podrá ser usada en toda su jerarquía de vistas. Es muy sencillo, es decir, metemos en el environment una clase instanciada y esta clase podrá ser usada en todas sus subvistas.
Tabla de contenido
EnvironmentObject es otro Property Wrapper que usamos para proporcionar desde alguna vista padre una clase que podrá ser usada en toda su jerarquía de vistas. Es muy sencillo, es decir, metemos en el environment una clase instanciada y esta clase podrá ser usada en todas sus subvistas, como si fuera magia.
En uno de los post anteriores explicamos cuándo usar ObservedObject y StateObject. En ese caso, dijimos de usar StateObject la primera vez que usábamos un ViewModel y qué si ese tipo de ViewModel lo necesitábamos en otra de sus subvistas, entonces usar ObservedObject (si quieres saber más te aconsejo que lo leas). Esto te lo comento ya que lo vamos a usar en nuestro ejemplo.
EnvironmentObject en código
Vamos a crear una clase llamada ViewModel que conforme el protocolo ObservableObject. Y también vamos a crear 3 vistas llamadas View1, View2 y View3 para que sea más fácil de entender.
View1 tendrá en su interior View2, y View2 tendrá a View3, es decir:
En View1 mostraremos un text que mostrará el valor de una propiedad llamada counter que estará en nuestro ViewModel. View1 le pasará el ViewModel a View2 y View2 le pasará el ViewModel a View3 para que al pulsar un botón actualice la propiedad counter, y este cambio se propague y View1 muestre el valor actualizado.
Primero de todo lo que vamos hacer es crear nuestro ViewModel con una propiedad llamada counter:
El siguiente paso es renombrar ContentView a View1 y añadir el siguiente código:
Ahora creamos View2:
y por último la View3:
Falta conectar estas 3 vistas. Ahora vamos a meter View3 en View2, y View2 en View1. Y también le vamos a pasar el ViewModel de View1 a View2 y de View2 a View3. Así podremos modificar la propiedad counter de nuestro ViewModel en View3.
Por lo tanto View3 quedaría de la siguiente manera:
View2 quedaría:
y View1:
Ya está todo conectado. De esta manera si probamos nuestro código vemos como todo funciona perfectamente, al pulsar el botón en View3, se actualizar el valor en View1 y mostramos el valor correcto.
PERO si te fijas hemos tenido que pasar el ViewModel en toda la jerarquía de vistas, aunque en View2 no lo hemos usado, se lo hemos tenido que pasar para poderlo usar en View3. Imagínate que en lugar de tener 3 simples vistas tienes muchas más.
Es aquí donde entra en juego EnvironmentObject. Lo único que tenemos que hacer es usar en nuestra vista View1 el modificador .environmentObject y pasarle nuestro ViewModel instanciado:
De esta manera, simplificamos nuestro código en View2, ya que no nos hace falta pasarle el ViewModel:
y en View3 solo tenemos que cambiar el ObservedObject por EnvironmentObject.
En View3 coge la instancia que le hemos metido en View1 y la puede usar sin problemas. Aquí hay que ir con especial atención, ya que si no añadimos la clase instanciada en el modificador .environmentObject, nuestra app crashería al pulsar el botón de "Incrementar".