Este didSet pe @Obligatorii de fișiere specifice?

0

Problema

În esență, sunt cuiburi @Binding 3 straturi profunde.

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

Indiferent de struct am schimba doubleValue este cel care didSet va rula, astfel încât, de exemplu, dacă am schimba în LayerThree numai că o va imprima, nici unul dintre ceilalți vor.

Sunt capabil de a uita-te pentru schimbări cu .onChange(of: doubleValue) care va ajunge apoi rula atunci când se schimbă dar nu face sens pentru mine de ce didSet nu va alerga afară de pe struct unde s-a schimbat de la.

Este @Binding struct specifice?

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

Cel mai bun răspuns

1

Folosind proprietatea de observatori ca didSet pe valori înfășurat în PropertyWrappers nu va fi "normal" efect deoarece valoarea este stabilit în interiorul ambalajului.

În SwiftUI, dacă doriți pentru a declanșa o acțiune atunci când o valoare se schimbă, ar trebui să utilizați onChange(of:perform:) modificator.

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

Te-am prins, asa ca am crezut... e setat din cadrul struct care e setat, nu prin lanț.
Joe Scotto
0

Acum, toate de lucru:

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

rezultate de imprimare:

LayerOne: 64.58963263686678

LayerTwo: 64.58963263686678

LayerThree: 64.58963263686678

2021-11-22 18:20:58

Dar de ce ai nevoie pentru a trece obligatoriu așa? Nu ar trebui să didSet se declanșează indiferent de unde legarea este schimbat?
Joe Scotto

Cred că ne putem întreba de ce sau cum, pentru ca este Apple și sursă închisă. Pentru a face didSet începe să lucreze aveți nevoie de inițializare pentru Legare.
swiftPunk
0

Pentru a vedea de ce acest lucru se întâmplă, putem dezvălui zahăr sintactic de proprietate ambalaje. @Binding var doubleValue: Double se traduce prin:

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

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

Orice ai face în didSet va fi pus după linia _doubleValue.wrappedValue = newValue. Ar trebui să fie foarte evident de ce atunci când actualizați doubleValue în stratul 3, didSet de doubleValue în layer 2 sau 1 nu a fost sunat. Ele sunt pur și simplu diferite calculat proprietăți!

swiftPunk soluție funcționează prin a crea un nou caracter obligatoriu a căror setter seturi struct e doubleValue, prin urmare, de asteptare didSet:

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

În alte limbi

Această pagină este în alte limbi

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