@Environment di SwiftUI — apa itu, konsep kunci dan mekanisme

Penulis: IT Sectr Diterbitkan: 2026-06-25 Waktu membaca: 8 mnt

@Environment di SwiftUI — property wrapper untuk membaca nilai dari lingkungan sistem, yang secara otomatis disebarkan melalui hierarki View. Komponen ini menyediakan akses ke skema warna, locale, ukuran fon, managedObjectContext, dan puluhan parameter sistem lainnya. Menurut Apple Developer Documentation (2025), @Environment menjamin bahwa setiap perubahan nilai lingkungan akan memicu penggambaran ulang semua View yang berlangganan, memastikan pembaruan antarmuka yang reaktif tanpa panggilan manual.

Hal Penting

  • @Environment — property wrapper untuk membaca nilai lingkungan sistem SwiftUI
  • Skema warna, locale, dan ukuran fon — nilai sistem yang sering digunakan
  • Perubahan lingkungan apa pun memicu penggambaran ulang otomatis View yang berlangganan
  • Kunci kustom memungkinkan pembuatan nilai lingkungan sendiri melalui EnvironmentKey
  • @Environment — hanya baca; @EnvironmentObject — untuk tulis

Apa itu @Environment di SwiftUI?

@Environment — adalah property wrapper SwiftUI yang dirancang untuk membaca nilai dari lingkungan sistem. Lingkungan adalah wadah hierarkis nilai yang secara otomatis disebarkan SwiftUI dari View induk ke View anak. Setiap nilai lingkungan diidentifikasi oleh kunci — tipe yang sesuai dengan protokol EnvironmentKey.

Mekanisme lingkungan menyerupai dependency injection di tingkat framework: sistem menyediakan serangkaian nilai yang telah ditentukan — skema warna (terang/gelap), locale, ukuran fon, managedObjectContext untuk Core Data, dismiss untuk menutup layar, dan banyak lainnya. View yang mendeklarasikan @Environment dengan kunci tertentu secara otomatis menerima nilai saat ini dan digambar ulang saat nilainya berubah.

Arsitektur lingkungan SwiftUI didasarkan pada protokol EnvironmentValues — struktur yang berisi semua nilai sistem. Setiap nilai disimpan sebagai properti dari struktur ini dengan getter dan setter. @Environment menggunakan key path untuk mengakses properti tertentu: @Environment(\.colorScheme) — akses ke skema warna, @Environment(\.locale) — ke locale.

@Environment sebagai Property Wrapper

Property wrapper @Environment mengimplementasikan dua mekanisme kunci: membaca nilai dari lingkungan dan berlangganan perubahannya. Saat membuat View, SwiftUI menelusuri semua properti @Environment dan mengikatnya ke nilai yang sesuai dari konteks saat ini. Jika View induk mengubah nilai melalui modifier .environment(), semua View anak yang membaca nilai ini akan digambar ulang secara otomatis.

Fitur penting: @Environment mendukung nilai opsional. Jika nilai tidak ditetapkan dalam hierarki, nilai default yang didefinisikan di EnvironmentKey akan dikembalikan. Untuk kunci sistem, nilai default selalu masuk akal — misalnya, skema warna default .light. Untuk kunci kustom, pengembang sendiri yang menentukan nilai default dalam metode defaultValue protokol EnvironmentKey.

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

    var body: some View {
        VStack {
            Text("Skema saat ini: \(colorScheme == .dark ? "Dark" : "Light")")
            Text("Locale: \(locale.identifier)")
            Text("Ukuran fon: \(sizeCategory)")
        }
    }
}

Dalam contoh, View membaca tiga nilai lingkungan sistem. Saat colorScheme berubah — misalnya, pengguna mengaktifkan mode gelap di pengaturan — View secara otomatis digambar ulang dengan nilai baru. Demikian pula saat wilayah atau ukuran fon (Dynamic Type) berubah. View tidak perlu berlangganan pemberitahuan atau memanggil penyegaran — SwiftUI mengelola ini secara otomatis.

Nilai lingkungan sistem

SwiftUI menyediakan puluhan nilai lingkungan sistem yang mencakup berbagai aspek antarmuka dan perilaku. Skema warna (\.colorScheme) — salah satu nilai yang paling banyak diminta, memungkinkan penyesuaian antarmuka dengan tema terang dan gelap. Locale (\.locale) berisi pengaturan regional pengguna untuk memformat tanggal, angka, dan mata uang.

Untuk Core Data, digunakan managedObjectContext (\.managedObjectContext) — konteks yang diteruskan melalui lingkungan dari persistence container. Untuk navigasi, tersedia dismiss (\.dismiss) untuk menutup layar saat ini dan isPresented (\.isPresented) untuk tampilan modal. Untuk kalender dan zona waktu — masing-masing calendar dan timeZone.

Key PathTipeTujuan
\.colorSchemeColorSchemeTema terang atau gelap
\.localeLocalePengaturan regional
\.sizeCategoryContentSizeCategoryUkuran fon Dynamic Type
\.managedObjectContextNSManagedObjectContextKonteks Core Data
\.dismissDismissActionMenutup layar
\.calendarCalendarKalender saat ini
\.timeZoneTimeZoneZona waktu
\.horizontalSizeClassUserInterfaceSizeClassUkuran horizontal layar

Untuk mengakses nilai sistem, gunakan key path melalui titik: @Environment(\.dismiss) var dismiss. Kompiler memeriksa keberadaan key path di EnvironmentValues, jadi kunci yang salah akan menyebabkan kesalahan pada tahap kompilasi. Nilai sistem baru ditambahkan oleh Apple dengan setiap versi iOS — daftar saat ini tersedia di dokumentasi EnvironmentValues.

@Environment vs @EnvironmentObject

Meskipun namanya mirip, @Environment dan @EnvironmentObject menyelesaikan tugas yang berbeda. @Environment membaca nilai sistem atau kustom yang terdaftar melalui EnvironmentKey. @EnvironmentObject — adalah property wrapper untuk ObservableObject, yang diteruskan melalui lingkungan berdasarkan tipe, tanpa kunci eksplisit.

@EnvironmentObject digunakan untuk dependency injection: View induk membuat objek (misalnya, ViewModel) dan meneruskannya ke View anak melalui modifier .environmentObject(). View anak menerimanya melalui @EnvironmentObject dan dapat membaca serta mengubah propertinya. @Environment — hanya baca untuk nilai sistem dan tidak mendukung umpan balik.

Parameter@Environment@EnvironmentObject
TujuanNilai sistem dan kustomInjeksi ObservableObject
KunciKey path EnvironmentValuesBerdasarkan tipe objek
TulisHanya bacaBaca dan tulis
Nilai kustomMelalui EnvironmentKeyMelalui kelas ObservableObject
Nilai defaultAda (defaultValue)Tidak ada (harus diteruskan)

Dalam praktiknya: gunakan @Environment untuk mengakses parameter sistem (tema, locale, ukuran fon) dan konfigurasi kustom yang tidak berubah saat runtime. Gunakan @EnvironmentObject untuk meneruskan ViewModel atau layanan melalui hierarki View ketika status perlu diubah dari komponen anak.

Contoh kode @Environment

Mari kita lihat pembuatan nilai lingkungan kustom. Untuk ini, Anda perlu mendefinisikan struktur yang sesuai dengan protokol EnvironmentKey dan memperluas EnvironmentValues dengan properti baru. Ini memungkinkan penerusan konfigurasi tema atau pengaturan aplikasi melalui seluruh pohon View tanpa 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 }

Protokol EnvironmentKey memerlukan implementasi properti statis defaultValue — nilai yang akan digunakan jika View induk belum menetapkan lingkungan kustom. Ekstensi EnvironmentValues menambahkan properti terhitung appTheme, menggunakan subscript dengan kunci. Setelah itu, View mana pun dapat membaca nilai melalui @Environment(\.appTheme).

Menggunakan @Environment dengan kunci kustom

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("Mode gelap aktif")
                    .foregroundStyle(.white)
                    .background(Color.black)
            } else {
                Text("Mode terang aktif")
                    .foregroundStyle(.black)
                    .background(Color.white)
            }
        }
    }
}

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

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

ThemedView membaca dua lingkungan: appTheme kustom dan colorScheme sistem. Kombinasi ini memungkinkan implementasi pengaturan tema yang fleksibel: pengguna dapat memilih tema “Terang”, “Gelap”, atau “Sistem”. Jika sistem dipilih — nilai diambil dari colorScheme, yang secara otomatis berubah saat tema diganti di pengaturan iOS. View induk (ContentView) menetapkan nilai appTheme melalui modifier .environment().

Menggunakan dismiss untuk menutup layar

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

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

Contoh ini mendemonstrasikan penggunaan praktis dismiss — instance DismissAction dari lingkungan. Pemanggilan dismiss() sebagai fungsi menutup layar modal atau mengembalikan NavigationLink. Satu-satunya persyaratan — View harus ditampilkan secara modal atau berada di dalam NavigationStack. dismiss ditentukan secara otomatis dari konteks: jika View dibuka sebagai sheet — sheet ditutup, jika sebagai popover — popover ditutup.

Pertanyaan Umum

Bisakah nilai @Environment diubah dari View anak?

Tidak, @Environment dirancang hanya untuk baca. Untuk mengubah nilai, gunakan @EnvironmentObject dengan ObservableObject atau @Binding. EnvironmentKey kustom dapat memiliki setter di ekstensi, tetapi perubahan melalui setter tersebut tidak memicu pembaruan UI — ini secara teknis mungkin, tetapi tidak disarankan.

Apa perbedaan @Environment dengan @Binding?

@Binding menciptakan koneksi dua arah dengan sumber kebenaran (State, StateObject, ObservableObject). @Environment — pembacaan satu arah dari konteks hierarkis. @Binding cocok untuk meneruskan data ke View anak, @Environment — untuk akses ke pengaturan sistem atau global.

Bagaimana cara membuat nilai lingkungan sendiri?

Definisikan struktur yang mengimplementasikan protokol EnvironmentKey dengan static defaultValue. Kemudian perluas EnvironmentValues dengan properti yang memiliki getter/setter melalui subscript[key]. Setelah registrasi, gunakan @Environment(\.yourKey) untuk membaca dan .environment(\.yourKey, value) untuk menetapkan.

Nilai lingkungan apa saja yang tersedia di SwiftUI?

SwiftUI menyediakan lebih dari 50 nilai sistem: colorScheme, locale, sizeCategory, managedObjectContext, dismiss, calendar, timeZone, horizontalSizeClass, verticalSizeClass, accessibilityEnabled, layoutDirection, legibilityWeight dan lainnya. Daftar lengkap di dokumentasi EnvironmentValues.

Apakah @Environment berfungsi di Preview?

Ya, @Environment berfungsi di Preview, tetapi nilai default mungkin berbeda dari simulator. Untuk pengujian di Preview, gunakan modifier .environment() langsung di kode Preview: ThemedView().environment(\.colorScheme, .dark). Ini memungkinkan pemeriksaan visual berbagai keadaan lingkungan.

Ringkasan

  • @Environment — property wrapper untuk membaca nilai lingkungan sistem SwiftUI melalui key path
  • Skema warna, locale, ukuran fon, dan managedObjectContext — nilai sistem yang paling banyak digunakan
  • Perubahan lingkungan memicu penggambaran ulang otomatis semua View yang berlangganan
  • EnvironmentKey kustom memungkinkan memperluas lingkungan aplikasi dengan pengaturan global
  • @Environment — hanya baca; @EnvironmentObject — untuk ObservableObject dengan tulis
  • Modifier .environment() menetapkan nilai untuk View anak dalam hierarki
  • Gunakan @Environment untuk parameter sistem, @EnvironmentObject — untuk ViewModel dan layanan

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga