Ответ
Environment (окружение) в SwiftUI — это механизм для передачи зависимостей (данных, объектов, значений) через иерархию представлений без явной передачи через инициализаторы каждого view.
Основные инструменты:
@Environment— для чтения системных или кастомных значений.@EnvironmentObject— для передачи ссылочных типов (ObservableObject).- Модификатор
.environment()— для установки значений.
Как создать и использовать кастомное environment-значение:
- Определите ключ:
struct ThemeKey: EnvironmentKey { static let defaultValue: Color = .blue // Значение по умолчанию } - Расширьте
EnvironmentValues:extension EnvironmentValues { var theme: Color { get { self[ThemeKey.self] } set { self[ThemeKey.self] = newValue } } } -
Используйте в дочернем view:
struct ContentView: View { @Environment(.theme) var theme // Чтение значения var body: some View { Text("Hello") .foregroundColor(theme) } } - Установите значение в родительском view:
ParentView() .environment(.theme, .red) // Установка значенияКлючевое отличие от
@EnvironmentObject:@Environmentработает с value-типами и системными настройками (размер шрифта, locale), а@EnvironmentObject— для общих моделей данных (ObservableObject).
Ответ 18+ 🔞
Слушай, а вот эта ваша штука — Environment в SwiftUI. Ну, в натуре, механизм, чтобы не таскать данные через всю иерархию, как чемодан без ручки, понимаешь? Сука, блядь, чтобы не прокидывать каждому вьюхе в инициализатор, как какую-то сволочь, через десять родителей.
Основные инструменты, на которые можно опереться, пока не упал:
@Environment— это чтобы почитать какие-то системные или свои собственные, блядь, значения. Как будто из воздуха достать.@EnvironmentObject— это уже для тяжёлой артиллерии, для этих вашихObservableObject, ссылочных типов, которые везде нужны.- Модификатор
.environment()— это волшебная палочка, которой ты, сука, это самое значение в воздух и засовываешь.
Как сварганить своё собственное environment-значение, чтобы все ахнули:
- Выдумай ключ, ёпта:
struct ThemeKey: EnvironmentKey { static let defaultValue: Color = .blue // Значение по умолчанию, если сверху нихуя не положили } - Расширь
EnvironmentValues, как тётя Клава расширяет свою юбку после праздников:extension EnvironmentValues { var theme: Color { get { self[ThemeKey.self] } // Достаём set { self[ThemeKey.self] = newValue } // Кладём } } -
Используй в дочернем вью, как будто так и надо:
struct ContentView: View { @Environment(.theme) var theme // Просто взял и прочитал, блядь, из ниоткуда var body: some View { Text("Hello") .foregroundColor(theme) // И раскрасил им текст, красота ёбта! } } - А теперь, сука, установи это значение где-то наверху, в родительском вью:
ParentView() .environment(.theme, .red) // Всё, теперь всё ниже по течению будет красным, пиздец!
А теперь главное, блядь, отличие от @EnvironmentObject, чтобы в голове не путалось:
@Environment — это больше для value-типов (как Color) или системных настроек (типа размер шрифта, locale, эта вся хуйня). А @EnvironmentObject — это когда у тебя целая модель данных, ObservableObject, которая должна быть доступна всем, как водка на празднике. Первое — как передать флажок, второе — как передать целый бар с бухлом.