Es didSet en un @de Unión de archivo específico?

0

Pregunta

Básicamente, estoy de anidación @Binding 3 capas de profundidad.

struct LayerOne: View {
    @State private var doubleValue = 0.0
    
    var body: some View {
        LayerTwo(doubleValue: $doubleValue)
    }
}

struct LayerTwo: View {
    @Binding var doubleValue: Double {
        didSet {
            print(doubleValue)
        }
    }
    
    var body: some View {
        LayerThree(doubleValue: $doubleValue)
    }
}

struct LayerThree: View {
    @Binding var doubleValue: Double {
        didSet {
            print(doubleValue) // Only this print gets run when doubleValue is updated from this struct
        }
    }

    var body: Some view {
        // Button here changes doubleValue
    }
}

Lo struct puedo cambiar doubleValue es aquella en la que la didSet se consigue correr, así que por ejemplo si lo puedo cambiar en LayerThree sólo que uno va a imprimir, ninguno de los otros.

Yo soy capaz de ver los cambios con .onChange(of: doubleValue) que luego recibirá el correr cuando los cambios pero no tener sentido para mí ¿por qué didSet no consigue correr excepto en la estructura donde se ha cambiado de.

Es @Binding struct específico?

swift swiftui
2021-11-22 18:09:26
3

Mejor respuesta

1

El uso de la propiedad como observadores didSet en valores envueltos en PropertyWrappers no tendrá el "normal" efecto debido a que el valor se establece en el interior del contenedor.

En SwiftUI, si desea activar una acción cuando cambia un valor, debe utilizar el onChange(of:perform:) modificador.

struct LayerTwo: View {
    @Binding var doubleValue: Double
    
    var body: some View {
        LayerThree(doubleValue: $doubleValue)
          .onChange(of: doubleValue) { newValue 
            print(newValue)
          }
    }
}
2021-11-22 18:26:49

Gotcha, así como yo pensaba... es que se establece dentro de la estructura que se ha establecido, no a través de la cadena.
Joe Scotto
0

Ahora todos los que trabajan:

struct ContentView: View {
    
    var body: some View {
        
        LayerOne()
        
    }
    
}


struct LayerOne: View {
    
    @State private var doubleValue:Double = 0.0 {
        didSet {
            print("LayerOne:", doubleValue)
        }
    }
    
    var body: some View {
        LayerTwo(doubleValue: Binding(get: { return doubleValue }, set: { newValue in doubleValue = newValue } ))
    }
    
}

struct LayerTwo: View  {
    
    @Binding var doubleValue: Double {
        didSet {
            print("LayerTwo:", doubleValue)
        }
    }
    
    var body: some View {
        
        LayerThree(doubleValue: Binding(get: { return doubleValue }, set: { newValue in doubleValue = newValue } ))
    }
}




struct LayerThree: View  {
    
    @Binding var doubleValue: Double {
        didSet {
            print("LayerThree:", doubleValue) 
        }
    }
    
    var body: some View {
        
        Text(String(describing: doubleValue))
            
        Button("update value") {
            doubleValue = Double.random(in: 0.0...100.0)
        }
        .padding()
    }
    
}

imprimir los resultados:

LayerOne: 64.58963263686678

LayerTwo: 64.58963263686678

LayerThree: 64.58963263686678

2021-11-22 18:20:58

Pero, ¿por qué usted necesita para pasar el enlace de esa manera? No didSet activar independientemente de donde la unión se cambia?
Joe Scotto

Creo que no podemos preguntar por qué o cómo, porque es de Apple y de código cerrado. Para hacer didSet empezar a trabajar usted necesidad de inicialización para la Unión.
swiftPunk
0

A ver por qué ocurre esto, se puede develar el azúcar sintáctico de la propiedad de los envoltorios. @Binding var doubleValue: Double se traduce en:

private var _doubleValue: Binding<Double>
var doubleValue: Double {
    get { _doubleValue.wrappedValue }
    set { _doubleValue.wrappedValue = newValue }
}

init(doubleValue: Binding<Double>) {
    _doubleValue = doubleValue
}

Lo que usted hace en didSet se colocarán después de la línea _doubleValue.wrappedValue = newValue. Debe ser muy obvio por qué cuando se actualiza doubleValue en la capa 3, La didSet de doubleValue en la capa 2 o 1 no consigue llamado. Simplemente son diferentes calculada propiedades!

swiftPunk la solución funciona mediante la creación de una nueva unión cuya setter establece la estructura del doubleValue, de ahí a llamar didSet:

Binding(get: { return doubleValue }, 
        set: { newValue in doubleValue = newValue }
//                         ^^^^^^^^^^^^^^^^^^^^^^
//                         this will call didSet in the current layer
2021-11-22 18:37:59

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................