@Environment en SwiftUI — qué es, conceptos clave y mecanismo

Autor: IT Sectr Publicado: 2026-06-25 Tiempo de lectura: 8 min

@Environment en SwiftUI es un property wrapper para leer valores del entorno del sistema, distribuidos automáticamente a través de la jerarquía de Views. El componente proporciona acceso al esquema de colores, configuración regional, tamaño de fuente, managedObjectContext y decenas de otros parámetros del sistema. Según la Documentación de Apple Developer (2025), @Environment garantiza que cualquier cambio en un valor del entorno provoque un redibujado de todas las Views suscritas, proporcionando actualizaciones reactivas de la interfaz sin llamadas manuales.

Puntos clave

  • @Environment — un property wrapper para leer valores del entorno del sistema SwiftUI
  • Esquema de colores, configuración regional y tamaño de fuente son valores del sistema de uso común
  • Cambiar cualquier valor del entorno provoca el redibujado automático de las Views suscritas
  • Claves personalizadas permiten crear valores de entorno propios mediante EnvironmentKey
  • @Environment — solo lectura; @EnvironmentObject — para escritura

¿Qué es @Environment en SwiftUI?

@Environment es un property wrapper de SwiftUI diseñado para leer valores del entorno del sistema. El entorno es un contenedor jerárquico de valores que SwiftUI distribuye automáticamente desde las Views padre a las Views hijas. Cada valor del entorno se identifica mediante una clave — un tipo que cumple con el protocolo EnvironmentKey.

El mecanismo del entorno se asemeja a la inyección de dependencias a nivel del framework: el sistema proporciona un conjunto predefinido de valores — esquema de colores (claro/oscuro), configuración regional, tamaño de fuente, managedObjectContext para Core Data, dismiss para cerrar pantallas, y muchos otros. Una View que declara @Environment con una clave específica recibe automáticamente el valor actual y se redibuja cuando cambia.

La arquitectura del entorno de SwiftUI se basa en el protocolo EnvironmentValues — una estructura que contiene todos los valores del sistema. Cada valor se almacena como una propiedad de esta estructura con getter y setter. @Environment utiliza un key path para acceder a una propiedad específica: @Environment(\.colorScheme) — acceso al esquema de colores, @Environment(\.locale) — acceso a la configuración regional.

@Environment como Property Wrapper

El property wrapper @Environment implementa dos mecanismos clave: leer un valor del entorno y suscribirse a sus cambios. Cuando se crea una View, SwiftUI recorre todas las propiedades @Environment y las vincula con los valores correspondientes del contexto actual. Si una View padre cambia un valor mediante el modificador .environment(), todas las Views hijas que lean ese valor se redibujan automáticamente.

Una característica importante: @Environment admite valores opcionales. Si un valor no está establecido en la jerarquía, se devuelve el valor por defecto definido en EnvironmentKey. Para las claves del sistema, el valor por defecto siempre es razonable — por ejemplo, el esquema de colores por defecto es .light. Para claves personalizadas, el desarrollador define el valor por defecto en el método defaultValue del protocolo EnvironmentKey.

swift
struct EnvironmentReaderView: View {
    @Environment(\.colorScheme) var colorScheme
    @Environment(\.locale) var locale
    @Environment(\.sizeCategory) var sizeCategory

    var body: some View {
        VStack {
            Text("Current scheme: \(colorScheme == .dark ? "Dark" : "Light")")
            Text("Locale: \(locale.identifier)")
            Text("Font size: \(sizeCategory)")
        }
    }
}

En el ejemplo, la View lee tres valores del entorno del sistema. Cuando colorScheme cambia — por ejemplo, el usuario activó el modo oscuro en los ajustes — la View se redibuja automáticamente con el nuevo valor. De forma similar, cuando cambia la región o el tamaño de fuente (Dynamic Type). La View no necesita suscribirse a notificaciones ni llamar a refresh — SwiftUI gestiona esto automáticamente.

Valores del entorno del sistema

SwiftUI proporciona decenas de valores del entorno del sistema que cubren varios aspectos de la interfaz y el comportamiento. Esquema de colores (\.colorScheme) es uno de los valores más utilizados, permitiendo adaptar la interfaz a temas claro y oscuro. Configuración regional (\.locale) contiene la configuración regional del usuario para formatear fechas, números y monedas.

Para Core Data, se utiliza managedObjectContext (\.managedObjectContext) — un contexto pasado a través del entorno desde el contenedor de persistencia. Para navegación, están disponibles dismiss (\.dismiss) para cerrar la pantalla actual y isPresented (\.isPresented) para presentaciones modales. Para calendario y zona horaria — calendar y timeZone respectivamente.

Key PathTipoPropósito
\.colorSchemeColorSchemeTema claro u oscuro
\.localeLocaleConfiguración regional
\.sizeCategoryContentSizeCategoryTamaño de fuente Dynamic Type
\.managedObjectContextNSManagedObjectContextContexto de Core Data
\.dismissDismissActionCerrar pantalla
\.calendarCalendarCalendario actual
\.timeZoneTimeZoneZona horaria
\.horizontalSizeClassUserInterfaceSizeClassTamaño horizontal de pantalla

Para acceder a los valores del sistema, use el key path con un punto: @Environment(\.dismiss) var dismiss. El compilador verifica la existencia del key path en EnvironmentValues, por lo que una clave incorrecta provocará un error en tiempo de compilación. Apple agrega nuevos valores del sistema con cada versión de iOS — la lista completa está disponible en la documentación de EnvironmentValues.

@Environment vs @EnvironmentObject

A pesar de los nombres similares, @Environment y @EnvironmentObject tienen propósitos diferentes. @Environment lee valores del sistema o personalizados registrados mediante EnvironmentKey. @EnvironmentObject es un property wrapper para un ObservableObject pasado a través del entorno por tipo, sin una clave explícita.

@EnvironmentObject se utiliza para inyección de dependencias: una View padre crea un objeto (por ejemplo, ViewModel) y lo pasa a las Views hijas mediante el modificador .environmentObject(). Las Views hijas lo reciben a través de @EnvironmentObject y pueden tanto leer como modificar sus propiedades. @Environment, por otro lado, es de solo lectura para valores del sistema y no admite retroalimentación.

Parámetro@Environment@EnvironmentObject
PropósitoValores del sistema y personalizadosInyección ObservableObject
ClaveKey path de EnvironmentValuesPor tipo de objeto
EscrituraSolo lecturaLectura y escritura
Valor personalizadoMediante EnvironmentKeyMediante clase ObservableObject
Valor por defectoSí (defaultValue)No (debe pasarse)

En la práctica: use @Environment para acceder a parámetros del sistema (tema, configuración regional, tamaño de fuente) y configuraciones personalizadas que no cambian en tiempo de ejecución. Use @EnvironmentObject para pasar un ViewModel o servicio a través de la jerarquía de Views cuando sea necesario modificar el estado desde componentes hijos.

Ejemplos de código @Environment

Veamos la creación de un valor de entorno personalizado. Para ello, debe definir una estructura que cumpla con el protocolo EnvironmentKey y extender EnvironmentValues con una nueva propiedad. Esto permite pasar la configuración del tema o ajustes de la aplicación a través de todo el árbol de Views sin props.

swift
struct AppThemeKey: EnvironmentKey {
    static let defaultValue: AppTheme = .system
}

extension EnvironmentValues {
    var appTheme: AppTheme {
        get { self[AppThemeKey.self] }
        set { self[AppThemeKey.self] = newValue }
    }
}

enum AppTheme { case system, light, dark }

El protocolo EnvironmentKey requiere implementar la propiedad estática defaultValue — el valor que se utilizará si la View padre no ha establecido un entorno personalizado. Extender EnvironmentValues agrega una propiedad calculada appTheme mediante un subscript con la clave. Después de esto, cualquier View puede leer el valor a través de @Environment(\.appTheme).

Usando @Environment con una clave personalizada

swift
struct ThemedView: View {
    @Environment(\.appTheme) var appTheme
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        VStack {
            if appTheme == .dark || (appTheme == .system && colorScheme == .dark) {
                Text("Dark mode active")
                    .foregroundStyle(.white)
                    .background(Color.black)
            } else {
                Text("Light mode active")
                    .foregroundStyle(.black)
                    .background(Color.white)
            }
        }
    }
}

struct ContentView: View {
    @State private var selectedTheme = AppTheme.system

    var body: some View {
        ThemedView()
            .environment(\.appTheme, selectedTheme)
    }
}

ThemedView lee dos entornos: el personalizado appTheme y el del sistema colorScheme. La combinación permite una configuración flexible del tema: el usuario puede elegir el tema Claro, Oscuro o del Sistema. Si se selecciona Sistema, el valor se toma de colorScheme, que cambia automáticamente al alternar el tema en los ajustes de iOS. La View padre (ContentView) establece el valor de appTheme mediante el modificador .environment().

Usando dismiss para cerrar una pantalla

swift
struct ModalView: View {
    @Environment(\.dismiss) var dismiss
    @State private var name = ""

    var body: some View {
        NavigationStack {
            Form {
                TextField("Your name", text: $name)
                Button("Save") { dismiss() }
            }
            .navigationTitle("Edit Profile")
        }
    }
}

Este ejemplo demuestra el uso práctico de dismiss — una instancia de DismissAction del entorno. Llamar a dismiss() como función cierra la pantalla modal o retrocede el NavigationLink. El único requisito es que la View debe presentarse de forma modal o estar dentro de un NavigationStack. dismiss se determina automáticamente según el contexto: si la View se abre como sheet — se cierra el sheet, si como popover — se cierra el popover.

Preguntas frecuentes

¿Puedo cambiar un valor de @Environment desde una View hija?

No, @Environment es de solo lectura. Para cambiar valores, use @EnvironmentObject con ObservableObject o @Binding. Los EnvironmentKeys personalizados pueden tener un setter en la extensión, pero cambiar a través de él no activa actualizaciones de la interfaz — esto es técnicamente posible pero no recomendado.

¿En qué se diferencia @Environment de @Binding?

@Binding crea una conexión bidireccional con una fuente de verdad (State, StateObject, ObservableObject). @Environment es una lectura unidireccional desde el contexto jerárquico. @Binding es adecuado para pasar datos a una View hija, @Environment — para acceder a configuraciones del sistema o globales.

¿Cómo creo mi propio valor de entorno?

Defina una estructura que implemente el protocolo EnvironmentKey con un defaultValue estático. Luego extienda EnvironmentValues con una propiedad usando getter/setter mediante subscript[key]. Después del registro, use @Environment(\.yourKey) para leer y .environment(\.yourKey, value) para establecer.

¿Qué valores del entorno están disponibles en SwiftUI?

SwiftUI proporciona más de 50 valores del sistema: colorScheme, locale, sizeCategory, managedObjectContext, dismiss, calendar, timeZone, horizontalSizeClass, verticalSizeClass, accessibilityEnabled, layoutDirection, legibilityWeight y otros. Lista completa en la documentación de EnvironmentValues.

¿Funciona @Environment en Preview?

Sí, @Environment funciona en Preview, pero los valores por defecto pueden diferir del simulador. Para probar en Preview, use el modificador .environment() directamente en el código de Preview: ThemedView().environment(\.colorScheme, .dark). Esto permite verificar visualmente diferentes estados del entorno.

Resumen

  • @Environment — un property wrapper para leer valores del entorno del sistema SwiftUI mediante key path
  • Esquema de colores, configuración regional, tamaño de fuente y managedObjectContext son los valores del sistema más utilizados
  • Cambiar un valor del entorno provoca el redibujado automático de todas las Views suscritas
  • EnvironmentKey personalizado permite extender el entorno de la aplicación con configuraciones globales
  • @Environment — solo lectura; @EnvironmentObject — para ObservableObject con acceso de escritura
  • El modificador .environment() establece un valor para las Views hijas en la jerarquía
  • Use @Environment para parámetros del sistema, @EnvironmentObject — para ViewModel y servicios

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también