简体   繁体   English

在watchOS中使用environmentObject

[英]Using environmentObject in watchOS

I am trying to use environmentObject in a watchOS6 app to bind my data model to my view. 我试图在watchOS6应用程序中使用environmentObject将我的数据模型绑定到我的视图。

I have created a simple, stand-alone Watch app in Xcode 11. 我在Xcode 11中创建了一个简单的独立Watch应用程序。

I created a new DataModel class 我创建了一个新的DataModel

import Combine
import Foundation
import SwiftUI

final class DataModel: BindableObject {

    let didChange = PassthroughSubject<DataModel,Never>()

    var aString: String = "" {
        didSet {
            didChange.send(self)
        }
    }

}

In my ContentView struct I bind this class using @EnvironmentObject - 在我的ContentView结构中,我使用@EnvironmentObject绑定此类 -

struct ContentView : View {

    @EnvironmentObject private var dataModel: DataModel

    var body: some View {
        Text($dataModel.aString.value)
    }
}

Finally, I attempt to inject an instance of the DataModel into the environment in the HostingController class - 最后,我尝试将一个DataModel实例注入到HostingController类的环境中 -

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

But, I get an error: 但是,我收到一个错误:

Cannot convert return expression of type '_ModifiedContent<ContentView, _EnvironmentKeyWritingModifier<DataModel?>>' to return type 'ContentView'

The error is because the WKHostingController is a generic that needs a concrete type - WKHostingController<ContentView> in this case. 错误是因为WKHostingController是一个需要具体类型的泛型 - 在这种情况下是WKHostingController<ContentView>

A similar approach works perfectly with UIHostingController in an iOS app because UIHostingController isn't a generic class. 类似的方法与工作完美UIHostingController在iOS应用程序,因为UIHostingController不是一个泛型类。

Is there some other way to inject the environment to a watchOS view? 是否有其他方法将环境注入watchOS视图?

You can use type erasure, AnyView in the case of SwiftUI View . 您可以使用类型擦除, AnyView在SwiftUI的情况下View

I would refactor WKHostingController to return AnyView . 我将重构WKHostingController返回AnyView

This seems to compile fine on my end. 这似乎在我的结尾编译好。

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

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

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