.environmentObject()视图运算符与@EnvironmentObject的作用是什么?

时间:2020-01-08 22:33:13

标签: swiftui swiftui-environment

我试图在这里爬出众所周知的Neophyte深渊。

我开始掌握@EnvironmentObject的用法,直到在文档中注意到.environmentObject()视图运算符为止。

这是我的代码:

import SwiftUI

struct SecondarySwiftUI: View {
    @EnvironmentObject var settings: Settings

    var body: some View {
        ZStack {
            Color.red
            Text("Chosen One: \(settings.pickerSelection.name)")
        }.environmentObject(settings) //...doesn't appear to be of use.
    }

    func doSomething() {}
}

我试图在视图上用.environmentObject()运算符替换@EnvironmentObject的使用。
我因缺少“设置”定义而遇到了编译错误。

但是,该代码可以在没有.environmentObject运算符的情况下正常运行。

所以我的问题是,为什么要有.environmentObject运算符?

.environmentObject()实例化一个environmentObject,而@environmentObject访问该实例化的对象吗?

1 个答案:

答案 0 :(得分:2)

以下是演示代码,用于显示EnvironmentObject.environmentObject用法的变体(带有内联注释):

struct RootView_Previews: PreviewProvider {
    static var previews: some View {
        RootView().environmentObject(Settings()) // environment object injection
    }
}

class Settings: ObservableObject {
    @Published var foo = "Foo"
}

struct RootView: View {
    @EnvironmentObject var settings: Settings // declaration for request of environment object

    @State private var showingSheet = false
    var body: some View {
        VStack {
            View1() // environment object injected implicitly as it is subview
            .sheet(isPresented: $showingSheet) {
                View2() // sheet is different view hierarchy, so explicit injection below is a must
                    .environmentObject(self.settings) // !! comment this out and see run-time exception
            }
            Divider()
            Button("Show View2") {
                self.showingSheet.toggle()
            }
        }
    }
}

struct View1: View {
    @EnvironmentObject var settings: Settings // declaration for request of environment object
    var body: some View {
        Text("View1: \(settings.foo)")
    }
}

struct View2: View {
    @EnvironmentObject var settings: Settings // declaration for request of environment object
    var body: some View {
        Text("View2: \(settings.foo)")
    }
}

因此,在您的代码中ZStack并不声明需要环境对象,因此不使用.environmentObject修饰符。