I am learning Stanford CS193p, and everything went so well till switching LazyVGrid with HStack.
I checked my code with the one professor made, they are the same. But the confusing part of my code is that, when my emojiCount = 4, preview worked well, I can use LazyVGrid, however when I changed emojiCount value more than 4, like 5 or 24, it would crash right away.
The crash info is this:
And here is my code:
import SwiftUI
struct ContentView: View {
var emojis = ["🚔", "🚂", "🚀", "🚘", "🚂", "🚀", "🚘", "🚂", "🚀", "🚘", "🚂", "🚀", "🚘", "🚂", "🚀", "🚀", "🚘", "🚂", "🚀", "🚀", "🚘", "🚂", "🚀", "🚀", "🚘"]
@State var emojiCount = 4
var body: some View {
VStack {
LazyVGrid(columns:[GridItem(),GridItem(),GridItem()]) {
ForEach(emojis[0..<emojiCount], id: \.self) { emoji in
CardView(content: emoji)
}
}
.foregroundColor(.red)
Spacer()
HStack {
remove
Spacer()
add
}
.font(.largeTitle)
.padding(.horizontal)
}
.padding(.horizontal)
}
var remove: some View {
Button {
if emojiCount > 2 {
emojiCount -= 1
}
} label: {
Image(systemName:"minus.circle")
}
}
var add: some View {
Button {
if emojiCount < emojis.count {
emojiCount += 1
}
} label: {
Image(systemName:"plus.circle")
}
}
}
struct CardView: View {
var content: String
@State var isFaceUp: Bool = true
var body: some View {
ZStack {
let shape = RoundedRectangle(cornerRadius: 20)
if isFaceUp {
shape.fill().foregroundColor(.white)
shape.stroke(lineWidth: 3)
Text(content).font(.largeTitle)
} else {
shape.fill()
}
}
.onTapGesture {
isFaceUp = !isFaceUp
}
}
}
I tried to figure out the whole night, but I still don't know what's wrong with my code. Thank you so much!
Run the code in the simulator and you will see the error
Fatal error: each layout item may only occur once
This leads to the emojis. You have a lot of them but only 4 different types.
In a loop where the items are referenced by \.self
you are responsible for making sure that the items are unique.