简体   繁体   English

如何制作 SwiftUI 查看协议的属性

[英]How to make a SwiftUI View a property of a Protocol

I'm trying to extend a protocol so that a certain few impls of the protocol have a view associated with them.我正在尝试扩展协议,以便协议的某些含义具有与之关联的视图。 However, because a SwiftUI View is a protocol, this is proving to be a challenge.然而,因为 SwiftUI 视图是一个协议,这被证明是一个挑战。

import SwiftUI


protocol ParentProtocol {
  var anyProperty: String { get }
}

protocol ChildProtocol : ParentProtocol {
  associatedtype V
  var someView: V { get }
}

class ChildImpl : ChildProtocol {
  var someView : some View {
    Text("Hello World")
  }

  var anyProperty: String = ""

}

class ChildMgr {
  var child: ParentProtocol = ChildImpl()

  func getView() -> some View {
    guard let child = child as? ChildProtocol else { return EmptyView() }
    return child.someView
  }
}

Its not clear to me where to constrain the ChildProtocol's associated type to a View (or Text for that matter).我不清楚在哪里将 ChildProtocol 的关联类型限制为 View(或 Text)。

At the guard let child =... I get the following compiler error: Protocol 'ChildProtocol' can only be used as a generic constraint because it has Self or associated type requirementsguard let child =...我得到以下编译器错误: Protocol 'ChildProtocol' can only be used as a generic constraint because it has Self or associated type requirements

and when returning the chid's view I get: Member 'someView' cannot be used on value of protocol type 'ChildProtocol'; use a generic constraint instead当返回 chid 的视图时,我得到: Member 'someView' cannot be used on value of protocol type 'ChildProtocol'; use a generic constraint instead Member 'someView' cannot be used on value of protocol type 'ChildProtocol'; use a generic constraint instead

I think the answer may be in this thread: https://developer.apple.com/forums/thread/7350 but frankly its confusing on how to apply it to this situation.我认为答案可能在这个线程中: https://developer.apple.com/forums/thread/7350但坦率地说,它对如何将它应用于这种情况感到困惑。

Don't use runtime checks.不要使用运行时检查。 Use constrained extensions.使用受限扩展。

I also don't see a reason for you to be using classes.我也没有看到你使用课程的理由。

protocol ChildProtocol: ParentProtocol {
  associatedtype View: SwiftUI.View
  var someView: View { get }
}

final class ChildImpl: ChildProtocol {
  var someView: some View {
    Text("Hello World")
  }

  var anyProperty: String = ""
}

final class ChildMgr<Child: ParentProtocol> {
  var child: Child

  init(child: Child) {
    self.child = child
  }
}

extension ChildMgr where Child: ChildProtocol {
  func getView() -> some View {
    child.someView
  }
}

extension ChildMgr {
  func getView() -> some View {
    EmptyView()
  }
}

extension ChildMgr where Child == ChildImpl {
  convenience init() {
    self.init(child: .init())
  }
}

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

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