本質上,我嵌套了@Binding3 層。
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
}
}
無論我更改哪個結構doubleValue,didSet都會運行該結構,因此例如,如果我更改它,LayerThree只有一個將列印,其他任何一個都不會。
我能夠觀察更改,.onChange(of: doubleValue)然后在更改時運行這些更改,但對我來說為什么didSet除了在更改的結構上不會運行之外沒有任何意義。
@Binding結構是特定的嗎?
uj5u.com熱心網友回復:
使用屬性觀察器(例如didSet在包裝中的值上)PropertyWrappers不會具有“正常”效果,因為該值是在包裝器內設定的。
在 SwiftUI 中,如果要在值更改時觸發操作,則應使用onChange(of:perform:)修飾符。
struct LayerTwo: View {
@Binding var doubleValue: Double
var body: some View {
LayerThree(doubleValue: $doubleValue)
.onChange(of: doubleValue) { newValue
print(newValue)
}
}
}
uj5u.com熱心網友回復:
現在一切正常:
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()
}
}
列印結果:
第一層:64.58963263686678
第二層:64.58963263686678
第三層:64.58963263686678
uj5u.com熱心網友回復:
要了解為什么會發生這種情況,我們可以揭開屬性包裝器的語法糖。@Binding var doubleValue: Double翻譯成:
private var _doubleValue: Binding<Double>
var doubleValue: Double {
get { _doubleValue.wrappedValue }
set { _doubleValue.wrappedValue = newValue }
}
init(doubleValue: Binding<Double>) {
_doubleValue = doubleValue
}
無論您做什么,didSet都將放在該行之后_doubleValue.wrappedValue = newValue。很明顯為什么當你doubleValue在第 3 層更新時,第2 層或第 1 層的didSetofdoubleValue不會被呼叫。它們只是不同的計算屬性!
swiftPunk 的解決方案通過創建一個新的系結來作業,其 setter 設定結構的doubleValue,因此呼叫didSet:
Binding(get: { return doubleValue },
set: { newValue in doubleValue = newValue }
// ^^^^^^^^^^^^^^^^^^^^^^
// this will call didSet in the current layer
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/363654.html
