我的问题很简单,因为@EnvironmentObject可用于在多个视图之间共享对象,并且在几乎所有教程中,@ EnvironmentObject对象都可以像这样在SceneDelegate中设置和传递:
let userSettings = UserSettings()
let contentView = UserSettingsDemo().environmentObject(userSettings)
window.rootViewController = UIHostingController(rootView: contentView)
我可以不在@SceneDelegate中传递我的@EnvironmentObject对象,而是在其他任何View中传递它吗? 例如在UserSettingsDemo.swift中:
struct UserSettingsDemo: View {
var userSettings: UserSettings
var body: some View {
VStack {
//this is child view, and it may have other child views inside it,
//Like I said, I pass the @EnvironmentObject userSettings here as the
//start point, not in the SceneDelegate, so that FancyScoreView's child views
//can use userSettings as @EnvironmentObject
FancyScoreView().environmentObject(userSettings)
}
}
}
我可以像上面所说的那样使用@EnvironmentObject吗? 我问这个问题的原因是,在很多情况下我们无法做到,或者将我们认为是“全局”的所有信息传递给SceneDelegate是不可行的。有时,我们只能在中途获得一些需要全球化的东西。有时,在应用程序的起点正确传递所有全局内容甚至是一个不好的做法。
答案 0 :(得分:2)
由于.environmentObject
修饰符返回some View
,所以可以。
/// Supplies an `ObservableObject` to a view subhierachy. /// /// The object can be read by any child by using `EnvironmentObject`. /// /// - Parameter bindable: the object to store and make available to /// the view's subhiearchy. @inlinable public func environmentObject<B>(_ bindable: B) -> some View where B : ObservableObject
答案 1 :(得分:1)
struct ContentView: View {
var settings: UserSettings
var body: some View {
NavigationView {
VStack {
// A button that writes to the environment settings
Button(action: {
// Do something with settings
}) {
Text("Settings")
}
NavigationLink(destination: DetailView().environmentObject(settings)) {
Text("Show Detail View")
}
}
}
}
}
struct DetailView: View {
@EnvironmentObject var settings: UserSettings
var body: some View {
// A text view that reads from the environment settings
Text("Some text")
}
}
如您所见,我们不需要在场景委托中显式关联UserSettings实例。
但是,@ EnvironmentObject用于应与整个应用程序中的所有视图共享的数据。这样一来,我们就可以在任何需要的地方共享模型数据,设置,主题,同时还可以确保在数据更改时我们的视图自动保持更新。