@Environment a SwiftUI-ban — property wrapper a rendszerkörnyezet értékeinek olvasásához, amelyek automatikusan terjednek a View-hierarchiában. A komponens hozzáférést biztosít a színsémához, locale-hoz, betűmérethez, managedObjectContext-hez és több tucat egyéb rendszerparaméterhez. A Apple Developer Documentation (2025) szerint az @Environment garantálja, hogy a környezeti érték bármely változása az összes feliratkozott View újrarajzolását okozza, biztosítva a felület reaktív frissítését manuális hívások nélkül.
Főbb pontok
@Environment — egy SwiftUI property wrapper, amely a rendszerkörnyezetből való értékek olvasására szolgál. A környezet egy hierarchikus értéktároló, amelyet a SwiftUI automatikusan terjeszt a szülő View-któl a gyermek View-k felé. Minden környezeti értéket egy kulcs azonosít — egy típus, amely megfelel az EnvironmentKey protokollnak.
A környezeti mechanizmus a dependency injection-re emlékeztet keretrendszer szinten: a rendszer egy előre meghatározott értékkészletet biztosít — színséma (világos/sötét), locale, betűméret, managedObjectContext a Core Data számára, dismiss a képernyő bezárásához és még sok más. Az a View, amely @Environment-t deklarált egy adott kulccsal, automatikusan megkapja az aktuális értéket, és újrarajzolódik annak változásakor.
A SwiftUI környezet architektúrája az EnvironmentValues protokollon alapul — egy struktúrán, amely az összes rendszerértéket tartalmazza. Minden érték a struktúra egy tulajdonságaként tárolódik getterrel és setterrel. @Environment key path-et használ egy adott tulajdonság eléréséhez: @Environment(\.colorScheme) — hozzáférés a színsémához, @Environment(\.locale) — a locale-hoz.
A @Environment property wrapper két kulcsmechanizmust valósít meg: az érték olvasását a környezetből és a változásaira való feliratkozást. A View létrehozásakor a SwiftUI végigmegy az összes @Environment tulajdonságon, és összeköti őket a megfelelő értékekkel az aktuális kontextusból. Ha egy szülő View megváltoztatja az értéket a .environment() módosító segítségével, az összes gyermek View, amely ezt az értéket olvassa, automatikusan újrarajzolódik.
Fontos jellemző: az @Environment támogatja az opcionális értékeket. Ha egy érték nincs beállítva a hierarchiában, az EnvironmentKey-ben meghatározott alapérték kerül visszaadásra. A rendszerkulcsok esetében az alapérték mindig ésszerű — például az alapértelmezett színséma .light. Egyedi kulcsok esetében a fejlesztő maga határozza meg az alapértéket az EnvironmentKey protokoll defaultValue metódusában.
struct EnvironmentReaderView: View {
@Environment(\.colorScheme) var colorScheme
@Environment(\.locale) var locale
@Environment(\.sizeCategory) var sizeCategory
var body: some View {
VStack {
Text("Aktuális séma: \(colorScheme == .dark ? "Dark" : "Light")")
Text("Locale: \(locale.identifier)")
Text("Betűméret: \(sizeCategory)")
}
}
}
A példában a View három rendszerkörnyezeti értéket olvas. A colorScheme változásakor — például a felhasználó bekapcsolta a sötét módot a beállításokban — a View automatikusan újrarajzolódik az új értékkel. Hasonlóan a régió vagy a betűméret (Dynamic Type) változásakor. A View-nak nem kell feliratkoznia értesítésekre vagy frissítést hívnia — a SwiftUI ezt automatikusan kezeli.
A SwiftUI több tucat rendszerkörnyezeti értéket biztosít, amelyek a felület és viselkedés különböző aspektusait fedik le. Színséma (\.colorScheme) — az egyik legkeresettebb érték, amely lehetővé teszi a felület világos és sötét témához való igazítását. Locale (\.locale) a felhasználó regionális beállításait tartalmazza a dátumok, számok és valuták formázásához.
A Core Data számára a managedObjectContext (\.managedObjectContext) használatos — a kontextus, amely a persistence container-ből kerül átadásra a környezeten keresztül. Navigációhoz elérhető a dismiss (\.dismiss) az aktuális képernyő bezárásához és az isPresented (\.isPresented) modális nézetekhez. A naptárhoz és időzónához — calendar és timeZone.
| Key Path | Típus | Rendeltetés |
|---|---|---|
| \.colorScheme | ColorScheme | Világos vagy sötét téma |
| \.locale | Locale | Regionális beállítások |
| \.sizeCategory | ContentSizeCategory | Dynamic Type betűméret |
| \.managedObjectContext | NSManagedObjectContext | Core Data kontextus |
| \.dismiss | DismissAction | Képernyő bezárása |
| \.calendar | Calendar | Aktuális naptár |
| \.timeZone | TimeZone | Időzóna |
| \.horizontalSizeClass | UserInterfaceSizeClass | Vízszintes képernyőméret |
A rendszerértékek eléréséhez használjon key path-et ponton keresztül: @Environment(\.dismiss) var dismiss. A fordító ellenőrzi a key path létezését az EnvironmentValues-ban, így a hibás kulcs fordítási hibát okoz. Az Apple minden iOS-verzióval új rendszerértékeket ad hozzá — az aktuális lista az EnvironmentValues dokumentációban érhető el.
A hasonló nevek ellenére az @Environment és @EnvironmentObject különböző feladatokat old meg. Az @Environment az EnvironmentKey-en keresztül regisztrált rendszer- vagy egyedi értékeket olvassa. Az @EnvironmentObject — egy property wrapper az ObservableObject számára, amely típus alapján kerül átadásra a környezeten keresztül, explicit kulcs nélkül.
Az @EnvironmentObject dependency injection-re használatos: a szülő View létrehoz egy objektumot (például ViewModel-t), és átadja a gyermek View-knak a .environmentObject() módosító segítségével. A gyermek View-k @EnvironmentObject-en keresztül kapják meg, és mind olvashatják, mind módosíthatják annak tulajdonságait. Az @Environment viszont — csak olvasható a rendszerértékek számára, és nem támogat visszacsatolást.
| Paraméter | @Environment | @EnvironmentObject |
|---|---|---|
| Rendeltetés | Rendszer- és egyedi értékek | ObservableObject injekció |
| Kulcs | Key path EnvironmentValues | Objektum típusa szerint |
| Írás | Csak olvasható | Olvasás és írás |
| Egyedi érték | EnvironmentKey segítségével | ObservableObject osztály segítségével |
| Alapérték | Van (defaultValue) | Nincs (kötelező átadni) |
A gyakorlatban: használja az @Environment-t a rendszerparaméterek (téma, locale, betűméret) és a futásidőben nem változó egyedi konfigurációk eléréséhez. Használja az @EnvironmentObject-et a ViewModel vagy szolgáltatás View-hierarchián keresztüli átadásához, amikor az állapotot gyermek komponensekből kell módosítani.
Nézzük meg egy egyedi környezeti érték létrehozását. Ehhez meg kell határozni egy, az EnvironmentKey protokollnak megfelelő struktúrát, és ki kell terjeszteni az EnvironmentValues-t egy új tulajdonsággal. Ez lehetővé teszi a témakonfiguráció vagy alkalmazásbeállítások átadását a teljes View-fán propsok nélkül.
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 }
Az EnvironmentKey protokoll megköveteli a static defaultValue tulajdonság implementációját — azt az értéket, amely akkor használatos, ha a szülő View nem állított be egyedi környezetet. Az EnvironmentValues kiterjesztés hozzáadja az appTheme számított tulajdonságot, a subscript használatával a kulccsal. Ezt követően bármely View olvashatja az értéket az @Environment(\.appTheme) segítségével.
struct ThemedView: View {
@Environment(\.appTheme) var appTheme
@Environment(\.colorScheme) var colorScheme
var body: some View {
VStack {
if appTheme == .dark || (appTheme == .system && colorScheme == .dark) {
Text("Sötét mód aktív")
.foregroundStyle(.white)
.background(Color.black)
} else {
Text("Világos mód aktív")
.foregroundStyle(.black)
.background(Color.white)
}
}
}
}
struct ContentView: View {
@State private var selectedTheme = AppTheme.system
var body: some View {
ThemedView()
.environment(\.appTheme, selectedTheme)
}
}
A ThemedView két környezetet olvas: az egyedi appTheme-t és a rendszer colorScheme-t. A kombináció lehetővé teszi egy rugalmas témabeállítás implementációját: a felhasználó választhat „Világos”, „Sötét” vagy „Rendszer” témát. Ha a rendszer van kiválasztva — az érték a colorScheme-ból származik, amely automatikusan változik a téma iOS-beállításokban történő váltásakor. A szülő View (ContentView) a .environment() módosító segítségével állítja be az appTheme értékét.
struct ModalView: View {
@Environment(\.dismiss) var dismiss
@State private var name = ""
var body: some View {
NavigationStack {
Form {
TextField("Your name", text: $name)
Button("Mentés") { dismiss() }
}
.navigationTitle("Edit Profile")
}
}
}
Ez a példa a dismiss — egy DismissAction példány a környezetből — gyakorlati használatát mutatja be. A dismiss() függvényként való meghívása bezárja a modális képernyőt vagy visszatéríti a NavigationLink-et. Az egyetlen követelmény — a View-nak modálisan kell megjelennie vagy NavigationStack-en belül kell lennie. A dismiss automatikusan meghatározásra kerül a kontextusból: ha a View sheet-ként van megnyitva — a sheet bezáródik, ha popover-ként — a popover bezáródik.
Gyakran ismételt kérdések
Nem, az @Environment csak olvasásra szolgál. Az értékek megváltoztatásához használja az @EnvironmentObject-et ObservableObject-tel vagy a @Binding-et. Az egyedi EnvironmentKey-ok rendelkezhetnek setter-rel a kiterjesztésben, de az azon keresztüli változtatás nem váltja ki a UI frissítését — ez technikailag lehetséges, de nem ajánlott.
A @Binding kétirányú kapcsolatot hoz létre az igazság forrásával (State, StateObject, ObservableObject). Az @Environment — egyirányú olvasás a hierarchikus kontextusból. A @Binding alkalmas adatok gyermek View-ba történő átadására, az @Environment — rendszer- vagy globális beállítások elérésére.
Határozzon meg egy struktúrát, amely implementálja az EnvironmentKey protokollt static defaultValue-val. Ezután bővítse ki az EnvironmentValues-t egy getter/setter tulajdonsággal a subscript[key] segítségével. Regisztráció után használja az @Environment(\.yourKey) függvényt olvasáshoz és a .environment(\.yourKey, value) függvényt beállításhoz.
A SwiftUI több mint 50 rendszerértéket biztosít: colorScheme, locale, sizeCategory, managedObjectContext, dismiss, calendar, timeZone, horizontalSizeClass, verticalSizeClass, accessibilityEnabled, layoutDirection, legibilityWeight és mások. A teljes lista az EnvironmentValues dokumentációban található.
Igen, az @Environment működik a Preview-ban, de az alapértékek eltérhetnek a szimulátortól. A Preview-ban történő teszteléshez használja a .environment() módosítót közvetlenül a Preview kódban: ThemedView().environment(\.colorScheme, .dark). Ez lehetővé teszi a környezet különböző állapotainak vizuális ellenőrzését.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is