【问题标题】:Does not conform to String protocol SwiftUI Picker View不符合 String 协议 SwiftUI Picker View
【发布时间】:2019-11-18 06:11:08
【问题描述】:

我有一个简单的struct,我将以此为基础。现在它有一个字段,一个 Int。

struct Card: CustomStringConvertible  {
  let value: Int

  init(value: Int) {
    self.value = value
  }

  var description: String {
    return "\(String(value))"
  }
}

如果我这样做,我会得到卡片来打印它的价值

let c = Card(value: 1)
print(c)

现在,如果我将一组卡片放入 CardController 中,如下所示:

class CardController: ObservableObject {
  @Published
  var cards: [Card] = [
    Card(value: 1),
    Card(value: 2),
    Card(value: 3)
  ]

Picker(selection: $selectedCardValue, label: Text("Choose a card")) {
        ForEach(0..<cardController.cards.count) {
          Text(self.cardController.cards[$0])
        }
      }
      Text("You selected \(selectedCardValue)")

我会收到错误 Initializer 'init(_:)' requires that 'Card' conform to StringProtocol。我不确定为什么会收到此错误。如果我只是将cards 更改为[String] 类型和值["1", "2", "3"],则代码可以正常工作。

知道这里有什么问题吗?

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    正如 E.Coms 所说,解决方案是使用以下方法之一:

    Text(self.cardController.cards[$0].description)

    Text(String(describing: self.cardController.cards[$0]))

    这里解释了为什么你必须在 Text 初始化器中这样做,而不是 print()


    查看Text 的两个初始化器:

    init(verbatim content: String) (docs)

    init&lt;S&gt;(_ content: S) where S : StringProtocol (docs)

    您必须传递StringSubstringonly two types 符合StringProtocol。在这种情况下,即使您的类型符合 CustomStringConvertible,您仍然传递了 Card


    将此与类似print 的函数进行对比:

    func print(_ items: Any..., separator: String = " ", terminator: String = "\n") (docs)

    注意print 函数的参数用Any 表示,is explained as

    Any 可以表示任何类型的实例,包括函数类型。

    print function then converts 无论你传递给String

    每个项目的文本表示与调用 String(item) 获得的相同。

    String 有一个initializer,它采用符合CustomStringConvertible 的类型并返回description 属性。


    所以你可以写print(Card())而不是Text(Card()的原因是因为打印函数有一个通过String的中间步骤,可以理解你对CustomStringConvertible的一致性,但Text没有。如果Text 允许您将任何类型传递给它,那么它会更加模棱两可(“这种类型的文本表示形式是什么?”不一定立即显而易见,因为它取决于一组分层协议),并且需要更多工作对于 SwiftUI 系统,它已经做了很多。

    【讨论】:

    • 我非常感谢您的详尽解释。谢谢。
    • 由于某种原因 .description 对我不起作用,但 String(describing:... 成功了。谢谢!
    【解决方案2】:

    您可能会错过description

     ForEach(0..<cardController.cards.count) {
        Text(self.cardController.cards[$0].description)
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-28
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多