Исправьте «@EnvironmentObject may be missing as an ancestor» — и чем отличается @Environment?
Тап по «Settings» падает с «@EnvironmentObject may be missing as an ancestor of this view». Корень внедряет session, но представленный sheet его всё равно не находит.
Требования:
- Объясните, почему представление sheet не видит внедрённый объект.
- Исправьте так, чтобы
SettingsViewполучилsession.
struct RootView: View {
@StateObject private var session = Session()
@State private var showSettings = false
var body: some View {
Button("Settings") { showSettings = true }
.environmentObject(session)
.sheet(isPresented: $showSettings) {
SettingsView() // падает: session нет в окружении sheet
}
}
}
struct SettingsView: View {
@EnvironmentObject var session: Session
var body: some View { Text(session.username) }
}
Найдите и исправьте ошибку.
Представление прочитало @EnvironmentObject, который не внедрил ни один предок через .environmentObject(_:). Внедрите его на нужный sheet или назначение навигации — они не наследуют окружение вызвавшего. @Environment иной — значение по ключу с умолчанием.
- ✗Не внедряют объект в окружение sheet или назначения навигации
- ✗Путают
@EnvironmentObject(внедрённый объект) с@Environment(значение по ключу) - ✗Делают свойство опциональным, чтобы заглушить падение, вместо внедрения выше
- →Почему представленный sheet не наследует environment object вызвавшего его экрана?
- →Почему
@Environmentне может упасть из-за отсутствующего значения, как@EnvironmentObject?
A presented sheet (and a navigationDestination, and a fullScreenCover) starts a new environment branch — it does not automatically inherit the .environmentObject(_:) values of the view that presented it. So session is injected on the button, but SettingsView inside the sheet is in a different branch and reads an object nobody supplied, which traps at runtime.
Inject the object on the sheet's content directly:
.sheet(isPresented: $showSettings) {
SettingsView()
.environmentObject(session) // supply it into the sheet's branch
}
@Environment is different in kind: it reads a keyed value from the environment (\.dismiss, \.colorScheme, \.locale) and every key has a default value, so a missing injection just yields the default — it can never crash the way @EnvironmentObject does. Use @EnvironmentObject for your own model objects (and always inject them), and @Environment for system-provided keyed values.