在watchOS中使用environmentObject

时间:2019-06-12 06:15:00

标签: swift apple-watch watch-os swiftui watch-os-6

我试图在watchOS6应用中使用environmentObject将数据模型绑定到视图。

我已经在Xcode 11中创建了一个简单的独立Watch应用。

我创建了一个新的DataModel

import Combine
import Foundation
import SwiftUI

final class DataModel: BindableObject {

    let didChange = PassthroughSubject<DataModel,Never>()

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

}

在我的ContentView结构中,我使用@EnvironmentObject-

绑定了该类。
struct ContentView : View {

    @EnvironmentObject private var dataModel: DataModel

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

最后,我尝试将DataModel的实例注入到HostingController类的环境中-

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

但是,我得到一个错误:

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

错误是因为WKHostingController是泛型,需要一种具体的类型-在这种情况下为WKHostingController<ContentView>

由于UIHostingController不是通用类,因此类似的方法也可以完美地与iOS应用中的UIHostingController配合使用。

还有其他方法可以将环境注入watchOS视图吗?

3 个答案:

答案 0 :(得分:7)

对于SwiftUI AnyView,您可以使用类型擦除View

我将重构WKHostingController以返回AnyView

这似乎对我来说很好。

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

答案 1 :(得分:1)

对于像布雷特这样的人(在评论中)

"Property 'body' with type 'AnyView' cannot override a property with type 'ContentView'"

我遇到了同样的错误,因为我没有替换返回值并包装了要返回的ContentView。

即。这就是我的第一次尝试。 WKHostingController<ContentView> 那应该是 WKHostingController<AnyView>

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

答案 2 :(得分:0)

添加到Matteo的出色答案中,

如果您要使用委托,请按以下方式使用:

"display" : "fullscreen"