SwiftUI’da @Environment, sistem ortamından değerleri okumak için bir property wrapper’dır ve View hiyerarşisi boyunca otomatik olarak dağıtılır. Bileşen, renk şemasına, yerel ayarlara, yazı tipi boyutuna, managedObjectContext’e ve daha onlarca sistem parametresine erişim sağlar. Apple Developer Documentation (2025)’a göre, @Environment, ortam değerindeki herhangi bir değişikliğin abone olunan tüm View’ların yeniden çizilmesini tetikleyerek manuel çağrılar olmadan reaktif arayüz güncellemeleri sağladığını garanti eder.
Ana Hatlar
@Environment, sistem ortamından değerleri okumak için tasarlanmış bir SwiftUI property wrapper’dır. Ortam, SwiftUI’nin üst View’lardan alt View’lara otomatik olarak dağıttığı hiyerarşik bir değer kapsayıcısıdır. Her ortam değeri, EnvironmentKey protokolüne uyan bir tür olan bir anahtarla tanımlanır.
Ortam mekanizması, framework düzeyinde bağımlılık enjeksiyonuna (dependency injection) benzer: sistem önceden tanımlanmış bir değer kümesi sağlar — renk şeması (açık/koyu), yerel ayarlar, yazı tipi boyutu, Core Data için managedObjectContext, ekranları kapatmak için dismiss ve daha birçokları. Belirli bir anahtarla @Environment bildiren bir View, otomatik olarak geçerli değeri alır ve değiştiğinde yeniden çizilir.
SwiftUI ortam mimarisi, EnvironmentValues protokolüne dayanır — tüm sistem değerlerini içeren bir yapıdır. Her değer, getter ve setter ile bu yapının bir özelliği olarak saklanır. @Environment, belirli bir özelliğe erişmek için key path kullanır: @Environment(\.colorScheme) — renk şemasına erişim, @Environment(\.locale) — yerel ayarlara erişim.
Property wrapper @Environment iki temel mekanizma uygular: ortamdan bir değer okumak ve değişikliklerine abone olmak. Bir View oluşturulduğunda, SwiftUI tüm @Environment özelliklerini dolaşır ve bunları geçerli bağlamdan karşılık gelen değerlere bağlar. Bir üst View, .environment() değiştiricisi aracılığıyla bir değeri değiştirirse, bu değeri okuyan tüm alt View’lar otomatik olarak yeniden çizilir.
Önemli bir özellik: @Environment isteğe bağlı değerleri destekler. Hiyerarşide bir değer ayarlanmamışsa, EnvironmentKey’de tanımlanan varsayılan değer döndürülür. Sistem anahtarları için varsayılan değer her zaman makuldür — örneğin, varsayılan renk şeması .light’tır. Özel anahtarlar için geliştirici, EnvironmentKey protokolünün defaultValue yönteminde varsayılan değeri tanımlar.
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)")
}
}
}
Örnekte, View üç sistem ortamı değerini okur. colorScheme değiştiğinde — örneğin, kullanıcı ayarlardan koyu modu etkinleştirdiğinde — View otomatik olarak yeni değerle yeniden çizilir. Aynı şekilde bölge veya yazı tipi boyutu (Dynamic Type) değiştiğinde de. View’ın bildirimlere abone olması veya refresh çağırması gerekmez — SwiftUI bunu otomatik olarak yönetir.
SwiftUI, arayüz ve davranışın çeşitli yönlerini kapsayan düzinelerce sistem ortamı değeri sağlar. Renk şeması (\.colorScheme) en çok kullanılan değerlerden biridir ve arayüzün açık ve koyu temalara uyarlanmasına olanak tanır. Yerel ayarlar (\.locale), tarihleri, sayıları ve para birimlerini biçimlendirmek için kullanıcının bölgesel ayarlarını içerir.
Core Data için, managedObjectContext (\.managedObjectContext) kullanılır — kalıcılık kapsayıcısından ortam aracılığıyla iletilen bir bağlam. Gezinme için, geçerli ekranı kapatmak için dismiss (\.dismiss) ve modal sunumlar için isPresented (\.isPresented) mevcuttur. Takvim ve saat dilimi için — sırasıyla calendar ve timeZone.
| Key Path | Tür | Amaç |
|---|---|---|
| \.colorScheme | ColorScheme | Açık veya koyu tema |
| \.locale | Locale | Bölgesel ayarlar |
| \.sizeCategory | ContentSizeCategory | Dynamic Type yazı tipi boyutu |
| \.managedObjectContext | NSManagedObjectContext | Core Data bağlamı |
| \.dismiss | DismissAction | Ekranı kapat |
| \.calendar | Calendar | Geçerli takvim |
| \.timeZone | TimeZone | Saat dilimi |
| \.horizontalSizeClass | UserInterfaceSizeClass | Yatay ekran boyutu |
Sistem değerlerine erişmek için, noktalı key path kullanın: @Environment(\.dismiss) var dismiss. Derleyici, EnvironmentValues’da key path’in varlığını kontrol eder, bu nedenle yanlış bir anahtar derleme zamanı hatasına neden olur. Apple, her iOS sürümüyle yeni sistem değerleri ekler — tam liste EnvironmentValues dokümantasyonunda mevcuttur.
Benzer isimlere rağmen, @Environment ve @EnvironmentObject farklı amaçlara hizmet eder. @Environment, EnvironmentKey aracılığıyla kaydedilen sistem veya özel değerleri okur. @EnvironmentObject, açık bir anahtar olmadan türüne göre ortam aracılığıyla iletilen bir ObservableObject için property wrapper’dır.
@EnvironmentObject, bağımlılık enjeksiyonu için kullanılır: bir üst View bir nesne (örn. ViewModel) oluşturur ve .environmentObject() değiştiricisi aracılığıyla alt View’lara iletir. Alt View’lar bunu @EnvironmentObject aracılığıyla alır ve özelliklerini okuyup değiştirebilir. @Environment ise sistem değerleri için yalnızca okunabilirdir ve geri bildirimi desteklemez.
| Parametre | @Environment | @EnvironmentObject |
|---|---|---|
| Amaç | Sistem ve özel değerler | ObservableObject enjeksiyonu |
| Anahtar | EnvironmentValues key path | Nesne türüne göre |
| Yazma | Yalnızca okuma | Okuma ve yazma |
| Özel değer | EnvironmentKey aracılığıyla | ObservableObject sınıfı aracılığıyla |
| Varsayılan değer | Evet (defaultValue) | Hayır (iletilmelidir) |
Pratikte: sistem parametrelerine (tema, yerel ayarlar, yazı tipi boyutu) ve çalışma zamanında değişmeyen özel yapılandırmalara erişmek için @Environment kullanın. Durumun alt bileşenlerden değiştirilmesi gerektiğinde, View hiyerarşisi aracılığıyla bir ViewModel veya hizmet iletmek için @EnvironmentObject kullanın.
Özel bir ortam değeri oluşturmayı inceleyelim. Bunun için, EnvironmentKey protokolüne uyan bir yapı tanımlamanız ve EnvironmentValues’ı yeni bir özellikle genişletmeniz gerekir. Bu, props olmadan tüm View ağacı boyunca tema yapılandırmasını veya uygulama ayarlarını iletmenize olanak tanır.
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 }
EnvironmentKey protokolü, statik defaultValue özelliğinin uygulanmasını gerektirir — üst View özel bir ortam ayarlamamışsa kullanılacak değerdir. EnvironmentValues’ı genişletmek, anahtarla subscript kullanarak hesaplanmış bir appTheme özelliği ekler. Bundan sonra, herhangi bir View @Environment(\.appTheme) aracılığıyla değeri okuyabilir.
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 iki ortamı okur: özel appTheme ve sistem colorScheme. Kombinasyon, esnek tema yapılandırmasına olanak tanır: kullanıcı Açık, Koyu veya Sistem temasını seçebilir. Sistem seçilirse, değer iOS ayarlarında tema değiştirildiğinde otomatik olarak değişen colorScheme’dan alınır. Üst View (ContentView), .environment() değiştiricisi aracılığıyla appTheme değerini ayarlar.
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")
}
}
}
Bu örnek, dismiss’in pratik kullanımını gösterir — ortamdan bir DismissAction örneği. Bir işlev olarak dismiss() çağrısı, modal ekranı kapatır veya NavigationLink’i geri alır. Tek gereksinim, View’ın modal olarak sunulması veya bir NavigationStack içinde olmasıdır. dismiss, bağlamdan otomatik olarak belirlenir: View bir sheet olarak açılmışsa — sheet kapanır, popover olarak açılmışsa — popover kapanır.
Sıkça Sorulan Sorular
Hayır, @Environment yalnızca okunabilir. Değerleri değiştirmek için ObservableObject ile birlikte @EnvironmentObject veya @Binding kullanın. Özel EnvironmentKey’ler genişletmede setter’a sahip olabilir, ancak bu yolla değişiklik UI güncellemelerini tetiklemez — bu teknik olarak mümkündür ancak önerilmez.
@Binding, bir gerçeklik kaynağıyla (State, StateObject, ObservableObject) çift yönlü bir bağlantı oluşturur. @Environment, hiyerarşik bağlamdan tek yönlü bir okumadır. @Binding, bir alt View’a veri iletmek için uygundur, @Environment — sistem veya genel ayarlara erişmek için.
Statik bir defaultValue ile EnvironmentKey protokolünü uygulayan bir yapı tanımlayın. Ardından, subscript[key] aracılığıyla getter/setter kullanan bir özellikle EnvironmentValues’ı genişletin. Kayıttan sonra, okumak için @Environment(\.yourKey) ve ayarlamak için .environment(\.yourKey, value) kullanın.
SwiftUI 50’den fazla sistem değeri sağlar: colorScheme, locale, sizeCategory, managedObjectContext, dismiss, calendar, timeZone, horizontalSizeClass, verticalSizeClass, accessibilityEnabled, layoutDirection, legibilityWeight ve diğerleri. Tam liste EnvironmentValues dokümantasyonunda.
Evet, @Environment Preview’da çalışır, ancak varsayılan değerler simülatörden farklı olabilir. Preview’da test etmek için, Preview kodunda doğrudan .environment() değiştiricisini kullanın: ThemedView().environment(\.colorScheme, .dark). Bu, farklı ortam durumlarını görsel olarak kontrol etmenizi sağlar.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun