Je didSet na @Závazné konkrétní soubor?

0

Otázka

V podstatě, jsem hnízdění @Binding 3 vrstvy hluboké.

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

Podle toho, co struct změnit doubleValue je jedno kde didSet bude se běhat, takže například pokud jsem to změnit v LayerThree jen, že jeden bude tisknout, nikdo z ostatních.

Jsem schopen sledovat změny s .onChange(of: doubleValue) což se pak utéct, když se to mění, ale to nedává smysl pro mě proč didSet nechce se spustit až na struct, kde se to tu změnilo od.

Je @Binding struct konkrétní?

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

Nejlepší odpověď

1

Pomocí vlastnosti jako pozorovatelé didSet na hodnoty, zabalené v PropertyWrappers nebudou mít "normální" účinek, protože hodnota je nastavena uvnitř obalu.

V SwiftUI, pokud chcete spustí akci, když se změní hodnota, měli byste použít 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

Chápu, takže přesně jak jsem si myslel... je to nastavit v rámci struct, který je nastaven, není přes řetěz.
Joe Scotto
0

Teď všichni pracují:

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 tisku:

LayerOne: 64.58963263686678

LayerTwo: 64.58963263686678

LayerThree: 64.58963263686678

2021-11-22 18:20:58

Ale proč si třeba předat závazné, že způsob, jak? Neměl didSet se spustí bez ohledu na to, kde vazba je změnil?
Joe Scotto

Myslím, že se nemůžeme ptát, proč nebo jak, protože to je Apple a uzavřený zdroj. Pro výrobu didSet začít pracovat, budete potřebovat inicializace za Závazné.
swiftPunk
0

Chcete vidět, proč se to stane, můžeme odhalit syntaktický cukr majetku obaly. @Binding var doubleValue: Double překládá se:

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

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

Co děláte v didSet bude uveden po řádku _doubleValue.wrappedValue = newValue. To by mělo být velmi jasné, proč při aktualizaci doubleValue ve vrstvě 3, didSet z doubleValue ve vrstvě 2 nebo 1 nevyvolají. Oni jsou prostě jiná počítačová vlastnosti!

swiftPunk řešení pracuje tím, že vytvoří nové vazby, jejichž seřizovač nastaví struct je doubleValueproto 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 jiných jazycích

Tato stránka je v jiných jazycích

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