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.

Combinar: actualizar los valores entre sí

El código de ejemplo aquí es muy simple. Los deslizadores actualizan valores dobles pero no al revés. ¿Cómo actualizar dos o más deslizadores entre sí utilizando Combine?

“` swift
struct Centimeters {
var value: Double
}

func updateInches() -> Double {
return value / 2.54
}

struct Inches {
var value: Double
}

func updateCentimeters() -> Double {
return value * 2.54
}

class SizeValueModel: ObservableObject {
@Published var centimeters: Centimeters
@Published var inches: Inches
var cancellables = Set<anycancellable>()

<pre><code>init() {
self.centimeters = Centimeters(value: 1.0)
self.inches = Inches(value: 0.393701)

$centimeters.sink {
self.inches.value = $0.updateInches()
}.store(in: &cancellables)
</code></pre>

// $inches.sink {
// self.centimeters.value = $0.updateCentimeters()
// }.store(in: &cancellables)
}
}

struct ContentView: View {
@StateObject var model = SizeValueModel()
var body: some View {
Slider(value: $model.centimeters.value, in: 0…100, label: {
Text("(model.centimeters.value)")
})
Slider(value: $model.inches.value, in: 0…39.3701, label: {
Text("(model.inches.value)")
})
}
}
“`

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para actualizar dos o más deslizadores entre sí, es necesario utilizar el patrón Publisher y Subscriber del framework Combine. Puedes lograr esto agregando otro sink al modelo SizeValueModel que escuche los cambios en la propiedad inches y actualice la propiedad centimeters en consecuencia.

    Aquí te mostramos cómo puedes actualizar la clase SizeValueModel para lograr esto:

    class SizeValueModel: ObservableObject {
        @Published var centimeters: Centimeters
        @Published var inches: Inches
        var cancellables = Set<anycancellable>()
    
        init() {
            self.centimeters = Centimeters(value: 1.0)
            self.inches = Inches(value: 0.393701)
    
            $centimeters.sink {
                self.inches.value = $0.updateInches()
            }.store(in: &cancellables)
    
            $inches.sink {
                let cmValue = $0.updateCentimeters()
                // Actualiza el valor de centímetros solo si es diferente del valor actual
                if self.centimeters.value != cmValue {
                    self.centimeters.value = cmValue
                }
            }.store(in: &cancellables)
        }
    }
    

    En el modelo SizeValueModel actualizado, agregamos otro sink que escucha los cambios en la propiedad inches. Dentro de esta clausura de sink, actualizamos la propiedad centimeters calculando el valor correspondiente en centímetros utilizando la función updateCentimeters() de la estructura Inches. Sin embargo, también agregamos una verificación para verificar si el nuevo valor en centímetros es diferente del valor actual antes de actualizarlo, para evitar un ciclo infinito.

    Con este modelo SizeValueModel actualizado, ambos deslizadores se actualizarán entre sí cuando se cambien.

Comments are closed.