Je didSet na @Záväzné súbor konkrétne?

0

Otázka

V podstate, som hniezdiacich @Binding 3 vrstvy hlboké.

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

Podľa toho, čo struct som zmeniť doubleValue je jedno kde didSet dostanete spustiť, takže napríklad ak by som ho zmeniť v LayerThree len to, že jeden z nich bude tlačiť, žiadne iné bude.

Som schopný sledovať zmeny s .onChange(of: doubleValue) čo bude potom dostať spustenie, keď sa to zmení, ale to nie je vyznať sa v mi prečo didSet nebudú spustiť okrem na struct, kde je to zmenilo, od.

Je @Binding struct konkrétne?

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

Najlepšiu odpoveď

1

Pomocou majetok ako pozorovatelia didSet na hodnoty zabalené v PropertyWrappers nebude mať "normálne" efekt, pretože hodnota je nastavená vo vnútri obalu.

V SwiftUI, ak chcete spustiť akciu, keď sa zmení hodnota, mali by ste použiť onChange(of:perform:) modifikátor.

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

Tommyho, tak ako som si myslel... to je nastavený od rámci struct, že je to set, nie hore cez reťazca.
Joe Scotto
0

Teraz všetky pracovné:

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

výsledky tlače:

LayerOne: 64.58963263686678

LayerTwo: 64.58963263686678

LayerThree: 64.58963263686678

2021-11-22 18:20:58

Ale prečo potrebujete odovzdať záväzné týmto spôsobom? Nemali by didSet dostať sa spustí bez ohľadu na to, kde záväzné sa zmenilo?
Joe Scotto

Myslím, že sme sa nemôže pýtať, prečo alebo ako, lebo to je Apple a uzavretý. Pre výrobu didSet začať pracovať potrebujete inicializácia za Záväzné.
swiftPunk
0

Vidieť, prečo sa to stane, môžeme odhaliť syntaktické cukru majetku obaly. @Binding var doubleValue: Double prekladá:

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

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

Čo robíte v didSet bude dať po line _doubleValue.wrappedValue = newValue. To by malo byť veľmi jasné, prečo pri aktualizácii doubleValue v vrstva 3, didSet z doubleValue v vrstva 2 alebo 1 nemá dostať tzv. Oni sú proste iné vypočítaná vlastnosti!

swiftPunk je riešenie funguje tak, že vytvoríte novú záväzné ktorých setter nastavuje struct je doubleValuepreto volá didSet:

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

V iných jazykoch

Táto stránka je v iných jazykoch

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