【问题标题】:How to iterate/foreach array in SwiftUI如何在 SwiftUI 中迭代/foreach 数组
【发布时间】:2020-02-16 23:59:48
【问题描述】:

我有这个字典数组。

let deckColors = [
    ["name": "blue", "desc": "desc1"],
    ["name": "yellow", "desc": "desc2"],
]

我的看法:

struct ContentView: View {
    var body: some View {
        ForEach(0 ..< deckColors.count) {value in
            Text(deckColors[value]["name"])
        }
    }
}

我怎样才能让它工作?当前出现此错误:协议类型Any 不能符合StringProtocol 因为只有具体类型才能符合协议

【问题讨论】:

    标签: ios swift xcode swiftui


    【解决方案1】:

    这对我有用

    struct ContentView: View {
        let deckColors = [
            ["name": "blue", "desc": "desc1"],
            ["name": "yellow", "desc": "desc2"],
        ]
    
        var body: some View {
            ForEach(0 ..< deckColors.count, id: \.self) {value in
                Text(String(self.deckColors[value]["name"]!))
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      这似乎是一种非常复杂的结构实现方式:

      struct DeckColor {
          var name: String
          var desc: String
      }
      
      let deckColors = [
          DeckColor(name: "blue", desc: "desc1"),
          DeckColor(name: "yellow", desc: "desc2")
      ]
      
      struct ContentView: View {
          var body: some View {
              ForEach(0 ..< deckColors.count) { value in
                  Text(deckColors[value].name)
              }
          }
      }
      

      您实现它的方式需要处理字典不包含"name" 值的情况。你可以这样做,但它更丑更脆弱:

      struct ContentView: View {
          var body: some View {
              ForEach(0 ..< deckColors.count) { value in
                  Text(deckColors[value]["name"] ?? "default text if name isn't there.")
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        我会将你的套牌颜色放入一个枚举中,然后对其进行迭代。

        enum DeckColor: String, CaseIterable {
            case blue
            case yellow
        
            var desc: String {
                switch self {
                    case .blue: return "desc1"
                    case .yellow: return "desc2"
                }
            }
        }
        
        struct ContentView: View {
            var body: some View {
                VStack(alignment: .leading) {
                    ForEach(DeckColor.allCases, id: \.self) { color in
                        Text(color.rawValue)
                    }
                }
            }
        }
        

        【讨论】:

        • 这将导致显示描述而不是颜色名称
        • 我更喜欢 Rob Napier 的建议。但无论如何,使用这种方法,您需要将枚举声明为 enum DeckColor: String, CaseIterable { 并将颜色 rawValue 传递给 Text 初始化程序。 Text(color.rawValue)
        • 我建议在结构上使用枚举的原因是,对于结构,每次运行应用程序时都必须运行初始化代码,“deckColors”越多,就越麻烦。如果您想在整个应用程序中访问它们,则必须每次都创建它们,或者创建它们的单例。 Enum 为您提供公共访问权限,是静态的,并为您提供类型安全。
        • 这完全取决于 OP 是否需要更改它们。如果您有枚举,这是不可能的。
        • 使用来自 OP 的字典表明他们可能对其中的所有值进行硬编码,但您提出了一个非常有效的观点。
        猜你喜欢
        • 2013-02-03
        • 1970-01-01
        • 2013-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-27
        • 2017-05-24
        • 1970-01-01
        相关资源
        最近更新 更多