Home > Back-end >  SwiftUI Observed Object not updating when published value changes
SwiftUI Observed Object not updating when published value changes

Time:06-30

I was following along with this lecture when I ran into some problems with my Observed Object updating. I have an @ObservedObject called EmojiMemoryGame with a published MemoryGame<String> variable called model. 'MemoryGame' is a struct that stores an array of cards, which each have a Bool variable that stores whether they are face up or not.

My ContentView is a View that shows each card in a grid on screen. When the user taps the card, viewModel.choose(card) toggles the isFaceUp variable of the card; the problem is that this does not cause the card to flip over on screen. This is my code in ContentView.swift:

struct ContentView: View {
    @ObservedObject var viewModel: EmojiMemoryGame
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 89))]) {
                ForEach(viewModel.cards) { card in
                    CardView(card: card)
                        .aspectRatio(2/3, contentMode: .fit)
                        .onTapGesture {
                            viewModel.choose(card)
                        }
                }
            }
        }
        .foregroundColor(.red)
        .padding(.horizontal)
    }
}

struct CardView: View {
    let card: MemoryGame<String>.Card
    
    var body: some View {
        ZStack {
            let shape = RoundedRectangle(cornerRadius: 20)
            
            if card.isFaceUp {
                shape
                    .fill()
                    .foregroundColor(.white)
                shape
                    .strokeBorder(lineWidth: 3)
                Text(card.content)
                    .font(.largeTitle)
            } else {
                shape
                    .fill()
            }
        }
    }
}

However, the code works as expected if I instead just copy/paste the code from CardView directly into the body of ContentView (see below), so I'm not really sure what is going on here.

struct ContentView: View {
    @ObservedObject var viewModel: EmojiMemoryGame
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 89))]) {
                ForEach(viewModel.cards) { card in
                    ZStack {
                        let shape = RoundedRectangle(cornerRadius: 20)
                        
                        if card.isFaceUp {
                            shape
                                .fill()
                                .foregroundColor(.white)
                            shape
                                .strokeBorder(lineWidth: 3)
                            Text(card.content)
                                .font(.largeTitle)
                        } else {
                            shape
                                .fill()
                        }
                    }
                    .aspectRatio(2/3, contentMode: .fit)
                    .onTapGesture {
                        viewModel.choose(card)
                    }
                }
            }
        }
        .foregroundColor(.red)
        .padding(.horizontal)
    }
}

Edit: Here is my EmojiMemoryGame.swift:

class EmojiMemoryGame: ObservableObject {
    static let emojis = ["           
  • Related