following this guide "Stanford university" I implemented a model(struct) named MemoryGame with a second struct inside named card ( implementing Identifiable ) with viewModel named EmojiMemoryGame(class) witch holds the model(MemoryGame) with a wrapper "@Published". in the contentView I have the viewModel(EmojiMemoryGame) with "@ObservedObject" wrapper.
This works fine, when the data changed the view get notified and updates, But I found 1 problem I don't understand, when the card struct ( the one in MemoryGame struct ) witch implements "Identifiable" implement another protocol ( i tried Equatable and Comparable ) the UI not getting updated ( I checked that the data is changing ). when implementing Equatable with the "func ==" the UI not updating at all, it become weirder when I remove the Equatable name from the struct declaration but I leave the "func ==" in there, its work.
I tried the same with Comparable and implemented the funcs "<" and "==", same thing, the @ObservedObject not working but if I remove the Comparable from the struct declaration its works.
*side question: when I removed Equatable from the struct but left the "==" func inside its still gave me the option to compare both object like it still implements Equatable. is this normal ?
I new to this and still don't know how to debug the objectWillChange.send() ( I tried but so far I failed I think )
the code is below
this is the model MemoryGame, I commented out the protocols that brake the functionality
import Foundation
struct MemoryGame<CardContent> {
var cards : [Card]
mutating func choose(card : Card) {
cards[index].isFaceUp = !cards[index].isFaceUp
}
struct Card : Identifiable /* , Equatable , Comparable */ {
// static func < (lhs: MemoryGame<CardContent>.Card, rhs: MemoryGame<CardContent>.Card) -> Bool {
// lhs.id < rhs.id
// }
//
// static func == (lhs: MemoryGame<CardContent>.Card, rhs: MemoryGame<CardContent>.Card) -> Bool {
// lhs.id == rhs.id
// }
//
static func == (lhs: Card, rhs: Card) -> Bool {
return lhs.id == rhs.id
}
var isFaceUp : Bool = true
var isMatched : Bool = false
var content : CardContent
var id : Int
}
}
this is the viewModel EmojiMemoryGame
import SwiftUI
class EmojiMemoryGame : ObservableObject {
typealias CoreGame = MemoryGame<String>
@Published private var model : CoreGame = EmojiMemoryGame.createMemoryGame()
func choose(card:CoreGame.Card) {
model.choose(card: card)
}
}
and this is the contentVIew
import SwiftUI
struct EmojiMemoryGameView: View {
@ObservedObject var viewModel : EmojiMemoryGame
var body: some View {
HStack {
ForEach(viewModel.cards) { card in
CardView(card: card).onTapGesture {
self.viewModel.choose(card: card)
}
}
}
.padding()
.foregroundColor(.orange)
}
}
struct CardView : View {
var card : MemoryGame<String>.Card
var body: some View {
ZStack {
if card.isFaceUp {
RoundedRectangle(cornerRadius: 10.0).fill().foregroundColor(.white)
RoundedRectangle(cornerRadius: 10.0).stroke(lineWidth: 3.0)
Text(card.content)
.font(.system(size: 200))
.minimumScaleFactor(0.1)
.lineLimit(1)
} else {
RoundedRectangle(cornerRadius: 10.0).fill()
}
}.aspectRatio(CGSize(width: 20, height: 30), contentMode: .fit)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
EmojiMemoryGameView(viewModel: EmojiMemoryGame())
}
}
question from:
https://stackoverflow.com/questions/65916694/swift-ui-observedobject-not-working-found-weird-behaviour-when-implementing-an 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…