es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

SwiftUI observa el objeto publicado de un objeto publicado.

Al presionar el botón, se agrega un jugador al juego y quiero observar los cambios en el juego a través del modelo de vista. Cuando presiono el botón, el contador no cambia.

Es casi como si necesitara que el juego dentro de ContentViewModel sea tanto @ObservedObject como @Published.

¿Alguien puede ayudarme a entender los fundamentos de por qué esta configuración está mal y cómo puedo solucionarlo?

import SwiftUI
import Combine

class Juego: ObservableObject {
    @Published var jugadores: [String] = []

func agregarJugador(_ jugador: String) {
    jugadores.append(jugador)
}
}

class ContentViewModel: ObservableObject {
    @Published var juego: Juego {
        didSet {
            suscripcion = juego.objectWillChange.sink { [weak self] _ in
                self?.objectWillChange.send()
            }
        }
    }
    var suscripcion: AnyCancellable?

init(juego: Juego) {
    self.juego = juego
}
}

struct ContentView: View {
    @ObservedObject var viewModel: ContentViewModel

var body: some View {
    Text("Num jugadores: \(viewModel.juego.jugadores.count)")
        .padding()

    Button("Añadir jugador") {
        viewModel.juego.agregarJugador("jugador")
    }
}
}
Tags:  ,

Answer

  1. Avatar for davy.ai

    El problema con el código actual es que, aunque ContentViewModel está marcada como ObservableObject, no está observando los cambios en el objeto Game. Para observar los cambios en el objeto Game, necesitamos marcar la propiedad game en ContentViewModel como tanto @ObservedObject como @Published.

    class ContentViewModel: ObservableObject {
        @ObservedObject var game: Game {
            didSet {
                subscription = game.objectWillChange.sink { [weak self] _ in
                    self?.objectWillChange.send()
                }
            }
        }
        var subscription: AnyCancellable?
    
        init(game: Game) {
            self.game = game
        }
    }
    

    Esto permitirá que ContentViewModel observe cualquier cambio realizado en el objeto Game y actualice la vista en consecuencia.

Comments are closed.