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 no actualiza la vista utilizando @Published.

No puedo actualizar el color de mi texto basado en el estado actual de mi objeto. El texto debe cambiar de color según la variable de estado verdadero o falso.

Intenté simplificar el código de donde provienen los datos a continuación.

Mi contenido de vista:

struct ContentView: View {
  @StateObject var gm = GameManager()
  @State var openSetting = false

  var body: some View {
    Button {
      openSetting.toggle()
    } label: {
      Text("Ajustes")
    }
  }
}

ContentView tiene una Vista de Ajustes donde selecciono la configuración y donde quiero actualizar mi textColor basado en el estado del objeto.

struct SettingView: View {
  @StateObject var gm : GameManager

  var body: some View {
    ScrollView(.horizontal, showsIndicators: true) {
      HStack(spacing: 20) {
        ForEach(gm.cockpit.ecamManager.door.doorarray) { doorName in
          Button {
            gm.close(door: doorName.doorName)
          } label: {
            Text(doorName.doorName)
            // Aquí es donde quiero cambiar el color
              .foregroundColor(doorName.isopen ? .orange : .green)
          }
        }
      }
    }
  }
}

Los datos provienen de GameManager, que cuenta con una variable llamada cockpit:

class GameManager: NSObject, ObservableObject, ARSessionDelegate, ARSCNViewDelegate {
  @Published var cockpit = MakeCockpit() // se crea la cabina
  // hacer otras cosas
}

MakeCockpit:

class MakeCockpit: SCNNode, ObservableObject {
  @Published var ecamManager = ECAMManager()
  // hacer otras cosas
}

ECAMManager:

class ECAMManager: ObservableObject {
  @Published var door = ECAMDoor()
  @Published var stanby = ECAMsby()
}

Y finalmente… El array que quiero observar está en la clase ECAMDoor:

class ECAMDoor: ObservableObject {
  @Published var doorarray : [Door] = [] // MODELO
}

Todo funciona bien como se esperaba, pero el @Publish del array de puertas no actualiza mi color en la vista de ajustes. Necesito cerrar la vista y abrirla de nuevo para ver la actualización de color.

¿Alguien puede decirme dónde está mi error? Probablemente me perdí algo… espero haber sido claro (demasiadas instancias de clase dentro de otras clases).

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece ser que el problema está en la manera en que estás actualizando la variable doorName.isopen. Ya que isopen es una propiedad de la estructura Door, necesitas asegurarte de marcarla con @Published para que SwiftUI detecte los cambios y actualice la vista en consecuencia.

    Puedes actualizar la estructura Door de la siguiente manera:

    struct Door: Identifiable {
        let id = UUID()
        var doorName: String
        @Published var isopen: Bool
    }
    

    Al marcar isopen con @Published, estás diciéndole a SwiftUI que observe los cambios y actualice la vista automáticamente.

    Además, puede ser deseable envolver el HStack que contiene los botones dentro de un ForEach para que SwiftUI detecte correctamente los cambios en la propiedad doorarray. Aquí hay una versión actualizada de tu SettingView:

    struct SettingView: View {
        @StateObject var gm: GameManager
    
        var body: some View {
            ScrollView(.horizontal, showsIndicators: true) {
                HStack(spacing: 20) {
                    ForEach(gm.cockpit.ecamManager.door.doorarray) { door in
                        Button(action: {
                            gm.close(door: door.doorName)
                        }, label: {
                            Text(door.doorName)
                                .foregroundColor(door.isopen ? .orange : .green)
                        })
                    }
                }
            }
        }
    }
    

    Al envolver el HStack dentro de ForEach(gm.cockpit.ecamManager.door.doorarray), le estás diciendo a SwiftUI que actualice la vista siempre que doorarray cambie.

    Con estos cambios, tu vista debería actualizar el color de texto de los botones inmediatamente cuando cambie el estado.

Comments are closed.