How to iterate/foreach array in SwiftUI

10,965

Solution 1

This seems a very complex way to implement a struct:

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

The way you've implemented it requires dealing with the case that the dictionary does not include a "name" value. You can do that, but it's uglier and more fragile:

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

Solution 2

This works for me

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"]!))
        }
    }
}

Solution 3

I would put your deck colors into an enum and then iterate on that.

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)
            }
        }
    }
}
Share:
10,965
user2641891
Author by

user2641891

Updated on June 13, 2022

Comments

  • user2641891
    user2641891 almost 2 years

    I have this array of dictionaries.

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

    And my view:

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

    How can I make it work? Currently getting this error: Protocol type Any cannot conform to StringProtocol because only concrete types can conform to protocols