【问题标题】:How to inject .environmentObject() in watchOS6如何在 watchOS6 中注入 .environmentObject()
【发布时间】:2019-08-19 14:52:58
【问题描述】:

我想在 watchOS6 中创建 SwiftUI 视图时注入一个 EnvironmentObject。

但由于 WKHostingController 需要具体类型,因此我无法执行以下操作 ContentView().environmentObject(UserData())

class HostingController: WKHostingController<ContentView> {
    override var body: ContentView {
        return ContentView().environmentObject(UserData())
    }
}

此代码失败并出现以下错误:

无法将“some View”类型的返回表达式转换为“ContentView”类型的返回

我见过这样的解决方法: Using environmentObject in watchOS 这似乎是一种 hack 而不是正确的解决方案。

我在 Twitter 上询问了一位 watchOS 工程师,他的回答是把 .environmentObject(UserData()) 放在 ContentView() 的正文中。我尝试这样做,但 Xcode 报告错误。

那么有人找到了同样的方法吗?

【问题讨论】:

    标签: swift swiftui watchos-6


    【解决方案1】:

    链接中的解决方法使用AnyView,这是一个非常糟糕的主意。 Apple 工程师在其他几个问题和推文中已经解释过,AnyView 只能用于叶视图,否则会严重影响性能。

    至于第二个选项(将environmentObject 放在ContentView 中),它工作正常。这里有一个例子:

    class UserData: ObservableObject {
        @Published var show: Bool = true
    }
    
    struct ContentView: View {
        @State var model = UserData()
    
        var body: some View {
            SubView().environmentObject(model)
        }
    }
    
    struct SubView: View {
        @EnvironmentObject var model: UserData
    
        var body: some View {
            VStack {
                Text("Tap Me!").onTapGesture {
                    self.model.show.toggle()
                }
    
                if self.model.show {
                    Text("Hello World")
                }
            }
        }
    }
    

    【讨论】:

    • 谢谢!你是怎么想出来的?
    • 不客气……我是怎么想出来的?我不知道……我对 SwiftUI 的声明文件非常熟悉。我不知道我经历了多少次。干杯。
    • 我试过了,但在修改 ContentView 中的模型时遇到了问题,而不是更新视图。我必须将它作为环境对象显式传递给子视图并在那里对其进行修改以传播更改(如本例所示)。
    猜你喜欢
    • 2020-03-13
    • 1970-01-01
    • 2021-03-30
    • 2020-05-17
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    相关资源
    最近更新 更多