È didSet su @Associazione di file specifico?

0

Domanda

In pratica, sono la nidificazione @Binding 3 livelli di profondità.

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
    }
}

Qualunque sia la struttura cambia doubleValue è quello in cui l' didSet sarà lanciato, così per esempio se cambio in LayerThree solo che uno di stampa, nessuno degli altri si.

Io sono in grado di controllare le modifiche con .onChange(of: doubleValue) quale sarà quindi eseguire quando si cambia ma non fare senso per me perché didSet non ottenere eseguito, tranne che sulla struttura in cui è cambiato dal.

È @Binding struct specifico?

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

Migliore risposta

1

Usando la proprietà osservatori come didSet su valori avvolto in PropertyWrappers non avrà il "normale" effetto, perché il valore viene impostato all'interno del wrapper.

In SwiftUI, se si desidera attivare un'azione in caso di cambiamenti di valore, si dovrebbe utilizzare il onChange(of:perform:) modificatore.

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, così proprio come pensavo... è impostato dall'interno della struttura che è impostato, non attraverso la catena.
Joe Scotto
0

Ora tutti al lavoro:

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()
    }
    
}

i risultati di stampa:

LayerOne: 64.58963263686678

LayerTwo: 64.58963263686678

LayerThree: 64.58963263686678

2021-11-22 18:20:58

Ma perché hai bisogno di passare l'associazione che modo? Non didSet ottenere scatta a prescindere di dove l'associazione è cambiato?
Joe Scotto

Penso che non si può chiedere perché o come, perché è Apple e closed source. Per fare didSet iniziare a lavorare hai bisogno di inizializzazione per l'Associazione.
swiftPunk
0

Per capire perché questo accade, siamo in grado di svelare il "zucchero sintattico" di proprietà wrapper. @Binding var doubleValue: Double si traduce in:

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

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

Qualunque cosa tu faccia nella didSet sarà messo dopo la riga _doubleValue.wrappedValue = newValue. Dovrebbe essere molto evidente perché quando si aggiorna doubleValue nel livello 3, Il didSet di doubleValue nel livello 2 o 1 non chiamato. Sono semplicemente diversi calcolata proprietà!

swiftPunk la soluzione funziona con la creazione di una nuova associazione, la cui setter imposta della struttura doubleValuequindi la chiamata didSet:

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

In altre lingue

Questa pagina è in altre lingue

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