Same content in 2 cards

Hello there! I'm trying to create something in SwiftUI, but there's a problem: I can't have 2 cards with the same content, does anyone know a way to have the same emojis in 2 separate cards?

Here's my code:

import PlaygroundSupport
import SwiftUI

struct ContentView: View {
    var emojis: [String] = ["🐶", "🐱", "🐱", "🦊", "🦁", "🐝", "🐼", "🐷", "🐮"]
    var body: some View {
        LazyVGrid(columns: [GridItem(), GridItem(), GridItem()]) {
            ForEach(emojis, id: \.self, content: { emoji in
                emojiView(content: emoji)
            })
    }
}

    struct emojiView: View {
        var content: String = ""
        var body: some View {
            ZStack {
                RoundedRectangle(cornerRadius: 20)
                    .frame(width: 90, height: 120)
                    .foregroundColor(.yellow)
                Text(content).font(.largeTitle)
            }
        }
    }
}


PlaygroundPage.current.setLiveView(ContentView())
Answered by Claude31 in 707700022

That's because they have the same id in ForEach loop. In fact, the error messages are quite explicit.

ForEach<Array, String, emojiView>: the ID 🐱 occurs multiple times within the collection, this will give undefined results!

LazyVGridLayout: the ID 🐱 is used by multiple child views, this will give undefined results!

This works:

struct MyEmoji : Hashable {
    var char: String
    var num: Int
}

struct ContentView39: View {

    var emojis : [MyEmoji] = [MyEmoji(char: "🐶", num: 0), MyEmoji(char: "🐱", num: 1), MyEmoji(char: "🐱", num: 2), MyEmoji(char: "🦊", num: 3), MyEmoji(char: "🦁", num: 4), MyEmoji(char: "🐝", num: 5), MyEmoji(char: "🐼", num: 6), MyEmoji(char: "🐷", num: 7), MyEmoji(char: "🐮", num: 8)]

    var body: some View {
        LazyVGrid(columns: [GridItem(), GridItem(), GridItem()]) {
            ForEach(emojis, id: \.self, content: { emoji in
                emojiView(content: emoji.char)
            })
    }
}

Accepted Answer

That's because they have the same id in ForEach loop. In fact, the error messages are quite explicit.

ForEach<Array, String, emojiView>: the ID 🐱 occurs multiple times within the collection, this will give undefined results!

LazyVGridLayout: the ID 🐱 is used by multiple child views, this will give undefined results!

This works:

struct MyEmoji : Hashable {
    var char: String
    var num: Int
}

struct ContentView39: View {

    var emojis : [MyEmoji] = [MyEmoji(char: "🐶", num: 0), MyEmoji(char: "🐱", num: 1), MyEmoji(char: "🐱", num: 2), MyEmoji(char: "🦊", num: 3), MyEmoji(char: "🦁", num: 4), MyEmoji(char: "🐝", num: 5), MyEmoji(char: "🐼", num: 6), MyEmoji(char: "🐷", num: 7), MyEmoji(char: "🐮", num: 8)]

    var body: some View {
        LazyVGrid(columns: [GridItem(), GridItem(), GridItem()]) {
            ForEach(emojis, id: \.self, content: { emoji in
                emojiView(content: emoji.char)
            })
    }
}

I had a similar response in Xcode debug area where I got the following message:

ForEach<Array<Int>, Int, Text>: the ID 4 occurs multiple times within the collection, this will give undefined results!

for the following code:

import SwiftUI

struct ContentView: View {
    let numbers = [1, 2, 3, 4, 4, 5]
    var body: some View {
        List {
            ForEach(numbers, id: \.self) { number in
                Text(String(number))
            }
        }
    }
}

#Preview {
    ContentView()
}

In fact, the behavior is exactly what someone would expect to see:

Although I understood @Claude31's solution of adding a differentiating property for the same emojis or using UUID(), I am still confused about the following points:

  1. Why does passing the array elements that hold the same value create issues in the first place? It seems quite straightforward to print each number one by one and it worked for the case of integers anyway. What is the main reason why Xcode is not happy with the array elements of the same value?
  2. What if our goal is to loop an array of the elements of which must have the same value? How can we tackle that?
Same content in 2 cards
 
 
Q