简体   繁体   English

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

[英]In SwiftUI, can I pass @EnvironmentObject not in the SceneDelegate? Like pass it in any View

My question is simple, since @EnvironmentObject can be used to share object between multiple view, and in almost all tutorials the @EnvironmentObject objects are all setup and passed in the SceneDelegate like this:我的问题很简单,因为@EnvironmentObject 可用于在多个视图之间共享对象,并且在几乎所有教程中,@EnvironmentObject 对象都被设置并像这样在 SceneDelegate 中传递:

let userSettings = UserSettings()
let contentView = UserSettingsDemo().environmentObject(userSettings)
window.rootViewController = UIHostingController(rootView: contentView)

Can I pass my @EnvironmentObject object not in the SceneDelegate, but rather in any other View?我可以不在 SceneDelegate 中传递我的 @EnvironmentObject 对象,而是在任何其他视图中传递吗? for example in UserSettingsDemo.swift:例如在 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)
    }
}

} }

Can I use @EnvironmentObject like above what I said?我可以像上面所说的那样使用 @EnvironmentObject 吗? The reason I'm asking this question is that in lots of scenarios we couldn't or it's not feasible to pass all we think it's 'Global' to SceneDelegate.我问这个问题的原因是,在很多情况下,我们不能或不可能将我们认为是“全局”的所有内容传递给 SceneDelegate。 Sometimes we can only get something that need to be global in the mid way.有时我们只能在中途得到一些需要全球化的东西。 sometimes it's even a bad practice to pass all global stuff right in the start point of the app.有时在应用程序的起点传递所有全局内容甚至是一种不好的做法。

As .environmentObject modifier returns some View , so yes, you can.由于.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
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")
    }
}

As you can see, we didn't need to explicitly associate the UserSettings instance in our scene delegate.如您所见,我们不需要在场景委托中显式关联 UserSettings 实例。

However @EnvironmentObject is used for data that should be shared with all views in your entire app.但是@EnvironmentObject 用于应该与整个应用程序中的所有视图共享的数据。 This lets us share model data, settings, theme, anywhere it's needed, while also ensuring that our views automatically stay updated when that data changes.这让我们可以在任何需要的地方共享模型数据、设置、主题,同时还确保我们的视图在数据更改时自动保持更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM