代码之家  ›  专栏  ›  技术社区  ›  Paulw11

在watchos中使用environmentobject

  •  2
  • Paulw11  · 技术社区  · 5 年前

    我想用 environmentObject 在watchos6应用程序中,将我的数据模型绑定到我的视图。

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

    我创造了一个新的 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)
        }
    }
    

    最后,我尝试注入 数据模型 进入环境中 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应用程序中,因为 主机控制器 不是泛型类。

    是否有其他方法将环境注入watchos视图?

    1 回复  |  直到 5 年前
        1
  •  25
  •   Matteo Pacini    5 年前

    你可以使用类型擦除, AnyView 以迅捷为例 View .

    我要重构 WKHostingController 返回 任何视图 .

    在我看来这本书写得不错。

    class HostingController : WKHostingController<AnyView> {
        override var body: AnyView {
            return AnyView(ContentView().environmentObject(DataModel()))
        }
    }
    
        2
  •  1
  •   mapes911    5 年前

    对于像布雷特这样的人

    "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()))
        }
    }