I am following the CS193P Stanford class, in which we are supposed to build a ForEach
view with an array of Cards
, defined in this struct :
struct MemoryGame<CardContent> {
private(set) var cards : [Card]
init(pairCount : Int, createCardContent : (Int) -> CardContent){
cards = []
for i in 0 ..< pairCount {
let content = createCardContent(i)
cards.append(Card(content : content, id : i*2))
cards.append(Card(content : content, id : i*2 + 1))
}
}
func choose(_ card: Card) {
}
struct Card : Identifiable {
var isFaceUp : Bool = true
var isMatched : Bool = false
var content : CardContent
var id: Int
}
}
As you can see, this struct conforms to the Identifiable
protocol, which according to the documentation should be enough for it to work in a ForEach
(Provided the type of id
is Hashable
, which Int
is)
Yet I get the following error :
Generic struct 'ForEach' requires that 'MemoryGame<String>.Card' conform to 'Hashable'
Why is it asking that ? The only thing the docs say is that the type of id
should be Hashable
, nothing about the entire struct being Hashable
The error hints also want me to add Equatable
but I can't seem to understand why, there is no reported error linked to that
NB : I am building in XCode 13 on macOS Monterey 12.0.1 with iOS 15 as a target
Here is then the ViewModel code for EmojiMemoryGame
:
class EmojiMemoryGame {
static let emojis = ["", "", "", "", "", "", "", ""]
private(set) var model = MemoryGame<String>(pairCount: 4) {i in emojis[i]}
var cards: Array<MemoryGame<String>.Card> {
model.cards
}
}
And the ContentView
:
struct ContentView: View {
let viewModel : EmojiMemoryGame
var body: some View {
VStack {
ScrollView {
LazyVGrid(columns : [GridItem(.adaptive(minimum : 65))]) {
ForEach(viewModel.cards) { card in // Error happens here
CardView(card)
.aspectRatio(2/3, contentMode: .fit)
}
}
}
.foregroundColor(.red)
}
.padding(.horizontal)
}
}