在SwiftUI中,可以在SceneDelegate中传递@EnvironmentObject吗?喜欢在任何视图中传递它

时间:2019-12-02 05:13:02

标签: ios swift swiftui

我的问题很简单,因为@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是不可行的。有时,我们只能在中途获得一些需要全球化的东西。有时,在应用程序的起点正确传递所有全局内容甚至是一个不好的做法。

2 个答案:

答案 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用于应与整个应用程序中的所有视图共享的数据。这样一来,我们就可以在任何需要的地方共享模型数据,设置,主题,同时还可以确保在数据更改时我们的视图自动保持更新。