@Environment in SwiftUI — cos’è, concetti chiave e meccanismo

Autore: IT Sectr Pubblicato: 2026-06-25 Tempo di lettura: 8 min

@Environment in SwiftUI è un property wrapper per leggere i valori dall’ambiente di sistema, distribuiti automaticamente attraverso la gerarchia delle View. Il componente fornisce accesso alla combinazione colori, alle impostazioni locali, alla dimensione del carattere, a managedObjectContext e a decine di altri parametri di sistema. Secondo la Documentazione Apple Developer (2025), @Environment garantisce che qualsiasi modifica a un valore dell’ambiente provochi un ridisegno di tutte le View sottoscritte, fornendo aggiornamenti reattivi dell’interfaccia senza chiamate manuali.

Punti chiave

  • @Environment — un property wrapper per leggere i valori dell’ambiente di sistema SwiftUI
  • Combinazione colori, impostazioni locali e dimensione del carattere sono valori di sistema comuni
  • Modificare qualsiasi valore dell’ambiente provoca il ridisegno automatico delle View sottoscritte
  • Chiavi personalizzate consentono di creare propri valori dell’ambiente tramite EnvironmentKey
  • @Environment — sola lettura; @EnvironmentObject — per la scrittura

Cos’è @Environment in SwiftUI?

@Environment è un property wrapper di SwiftUI progettato per leggere i valori dall’ambiente di sistema. L’ambiente è un contenitore gerarchico di valori che SwiftUI distribuisce automaticamente dalle View genitori alle View figlie. Ogni valore dell’ambiente è identificato da una chiave — un tipo conforme al protocollo EnvironmentKey.

Il meccanismo dell’ambiente ricorda l’iniezione di dipendenze a livello di framework: il sistema fornisce un insieme predefinito di valori — combinazione colori (chiaro/scuro), impostazioni locali, dimensione del carattere, managedObjectContext per Core Data, dismiss per chiudere gli schermi e molti altri. Una View che dichiara @Environment con una chiave specifica riceve automaticamente il valore corrente e si ridisegna quando cambia.

L’architettura dell’ambiente SwiftUI si basa sul protocollo EnvironmentValues — una struttura contenente tutti i valori di sistema. Ogni valore è memorizzato come proprietà di questa struttura con getter e setter. @Environment utilizza un key path per accedere a una proprietà specifica: @Environment(\.colorScheme) — accesso alla combinazione colori, @Environment(\.locale) — accesso alle impostazioni locali.

@Environment come Property Wrapper

Il property wrapper @Environment implementa due meccanismi chiave: leggere un valore dall’ambiente e sottoscriversi ai suoi cambiamenti. Quando viene creata una View, SwiftUI esamina tutte le proprietà @Environment e le collega ai valori corrispondenti del contesto corrente. Se una View genitore modifica un valore tramite il modificatore .environment(), tutte le View figlie che leggono quel valore vengono automaticamente ridisegnate.

Una caratteristica importante: @Environment supporta valori opzionali. Se un valore non è impostato nella gerarchia, viene restituito il valore predefinito definito in EnvironmentKey. Per le chiavi di sistema, il valore predefinito è sempre ragionevole — ad esempio, la combinazione colori predefinita è .light. Per le chiavi personalizzate, lo sviluppatore definisce il valore predefinito nel metodo defaultValue del protocollo 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)")
        }
    }
}

Nell’esempio, la View legge tre valori dell’ambiente di sistema. Quando colorScheme cambia — ad esempio, l’utente ha attivato la modalità scura nelle impostazioni — la View si ridisegna automaticamente con il nuovo valore. Allo stesso modo quando cambia la regione o la dimensione del carattere (Dynamic Type). La View non deve sottoscriversi alle notifiche o chiamare refresh — SwiftUI gestisce tutto automaticamente.

Valori dell’ambiente di sistema

SwiftUI fornisce decine di valori dell’ambiente di sistema che coprono vari aspetti dell’interfaccia e del comportamento. Combinazione colori (\.colorScheme) è uno dei valori più utilizzati, consentendo di adattare l’interfaccia ai temi chiaro e scuro. Impostazioni locali (\.locale) contiene le impostazioni regionali dell’utente per la formattazione di date, numeri e valute.

Per Core Data, viene utilizzato managedObjectContext (\.managedObjectContext) — un contesto passato attraverso l’ambiente dal contenitore di persistenza. Per la navigazione, sono disponibili dismiss (\.dismiss) per chiudere lo schermo corrente e isPresented (\.isPresented) per le presentazioni modali. Per calendario e fuso orario — calendar e timeZone rispettivamente.

Key PathTipoScopo
\.colorSchemeColorSchemeTema chiaro o scuro
\.localeLocaleImpostazioni regionali
\.sizeCategoryContentSizeCategoryDimensione carattere Dynamic Type
\.managedObjectContextNSManagedObjectContextContesto Core Data
\.dismissDismissActionChiudi schermo
\.calendarCalendarCalendario corrente
\.timeZoneTimeZoneFuso orario
\.horizontalSizeClassUserInterfaceSizeClassDimensione orizzontale schermo

Per accedere ai valori di sistema, utilizzare il key path con un punto: @Environment(\.dismiss) var dismiss. Il compilatore verifica l’esistenza del key path in EnvironmentValues, quindi una chiave errata causerà un errore di compilazione. Apple aggiunge nuovi valori di sistema con ogni versione di iOS — l’elenco completo è disponibile nella documentazione EnvironmentValues.

@Environment vs @EnvironmentObject

Nonostante i nomi simili, @Environment e @EnvironmentObject hanno scopi diversi. @Environment legge valori di sistema o personalizzati registrati tramite EnvironmentKey. @EnvironmentObject è un property wrapper per un ObservableObject passato attraverso l’ambiente per tipo, senza una chiave esplicita.

@EnvironmentObject è utilizzato per l’iniezione di dipendenze: una View genitore crea un oggetto (ad esempio ViewModel) e lo passa alle View figlie tramite il modificatore .environmentObject(). Le View figlie lo ricevono tramite @EnvironmentObject e possono leggere e modificare le sue proprietà. @Environment, invece, è di sola lettura per i valori di sistema e non supporta il feedback.

Parametro@Environment@EnvironmentObject
ScopoValori di sistema e personalizzatiIniezione ObservableObject
ChiaveKey path EnvironmentValuesPer tipo di oggetto
ScritturaSola letturaLettura e scrittura
Valore personalizzatoTramite EnvironmentKeyTramite classe ObservableObject
Valore predefinitoSì (defaultValue)No (deve essere passato)

In pratica: utilizzare @Environment per accedere ai parametri di sistema (tema, impostazioni locali, dimensione del carattere) e configurazioni personalizzate che non cambiano in fase di esecuzione. Utilizzare @EnvironmentObject per passare un ViewModel o un servizio attraverso la gerarchia delle View quando lo stato deve essere modificato da componenti figli.

Esempi di codice @Environment

Esaminiamo la creazione di un valore dell’ambiente personalizzato. Per farlo, è necessario definire una struttura conforme al protocollo EnvironmentKey ed estendere EnvironmentValues con una nuova proprietà. Ciò consente di passare la configurazione del tema o le impostazioni dell’app attraverso l’intero albero delle View senza 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 }

Il protocollo EnvironmentKey richiede l’implementazione della proprietà statica defaultValue — il valore che verrà utilizzato se la View genitore non ha impostato un ambiente personalizzato. L’estensione di EnvironmentValues aggiunge una proprietà calcolata appTheme utilizzando un subscript con la chiave. Dopodiché, qualsiasi View può leggere il valore tramite @Environment(\.appTheme).

Utilizzare @Environment con una chiave personalizzata

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 legge due ambienti: il personalizzato appTheme e il system colorScheme. La combinazione consente una configurazione flessibile del tema: l’utente può scegliere il tema Chiaro, Scuro o Sistema. Se viene selezionato Sistema, il valore viene preso da colorScheme, che cambia automaticamente quando si passa da un tema all’altro nelle impostazioni iOS. La View genitore (ContentView) imposta il valore appTheme tramite il modificatore .environment().

Utilizzare dismiss per chiudere uno schermo

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")
        }
    }
}

Questo esempio mostra l’uso pratico di dismiss — un’istanza di DismissAction dall’ambiente. Chiamare dismiss() come funzione chiude lo schermo modale o fa tornare indietro il NavigationLink. L’unico requisito è che la View sia presentata modalmente o si trovi all’interno di un NavigationStack. dismiss viene determinato automaticamente dal contesto: se la View è aperta come sheet — lo sheet viene chiuso, se come popover — il popover viene chiuso.

Domande frequenti

Posso modificare un valore @Environment da una View figlia?

No, @Environment è di sola lettura. Per modificare i valori, utilizzare @EnvironmentObject con ObservableObject o @Binding. Gli EnvironmentKeys personalizzati possono avere un setter nell’estensione, ma la modifica tramite esso non attiva aggiornamenti dell’interfaccia — è tecnicamente possibile ma non raccomandato.

Qual è la differenza tra @Environment e @Binding?

@Binding crea una connessione bidirezionale con una fonte di verità (State, StateObject, ObservableObject). @Environment è una lettura unidirezionale dal contesto gerarchico. @Binding è adatto per passare dati a una View figlia, @Environment — per accedere a impostazioni di sistema o globali.

Come creo il mio valore dell’ambiente?

Definire una struttura che implementi il protocollo EnvironmentKey con un defaultValue statico. Quindi estendere EnvironmentValues con una proprietà utilizzando getter/setter tramite subscript[key]. Dopo la registrazione, utilizzare @Environment(\.yourKey) per leggere e .environment(\.yourKey, value) per impostare.

Quali valori dell’ambiente sono disponibili in SwiftUI?

SwiftUI fornisce oltre 50 valori di sistema: colorScheme, locale, sizeCategory, managedObjectContext, dismiss, calendar, timeZone, horizontalSizeClass, verticalSizeClass, accessibilityEnabled, layoutDirection, legibilityWeight e altri. Elenco completo nella documentazione EnvironmentValues.

@Environment funziona in Preview?

Sì, @Environment funziona in Preview, ma i valori predefiniti possono differire dal simulatore. Per testare in Preview, utilizzare il modificatore .environment() direttamente nel codice Preview: ThemedView().environment(\.colorScheme, .dark). Ciò consente di verificare visivamente diversi stati dell’ambiente.

Riepilogo

  • @Environment — un property wrapper per leggere i valori dell’ambiente di sistema SwiftUI tramite key path
  • Combinazione colori, impostazioni locali, dimensione del carattere e managedObjectContext sono i valori di sistema più utilizzati
  • Modificare un valore dell’ambiente provoca il ridisegno automatico di tutte le View sottoscritte
  • EnvironmentKey personalizzato consente di estendere l’ambiente dell’app con impostazioni globali
  • @Environment — sola lettura; @EnvironmentObject — per ObservableObject con accesso in scrittura
  • Il modificatore .environment() imposta un valore per le View figlie nella gerarchia
  • Utilizzare @Environment per i parametri di sistema, @EnvironmentObject — per ViewModel e servizi

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche