这是一个演示我所看到的示例:
struct Tapper: View {
@Binding var incrementMe: Int
var body: some View {
Button("Button With Binding") {
incrementMe += 1
}
}
}
struct ContentView: View {
@State private var tapCount: Int = 0 {
didSet{
print("didSet tapCount = \(tapCount)")
}
}
var body: some View {
VStack {
Text("tapCount: \(tapCount)")
Tapper(incrementMe: $tapCount)
.padding(4.0)
Button("Button Without Binding") {
tapCount += 1
}
}
.padding()
}
}
ContentView
呈现此:
“Button With Binding”是来自
Tapper
结构的按钮,绑定回 tapCount
。 “无绑定按钮”是 ContentView
中直接递增 tapCount
的按钮(无绑定)。就视图而言,这两个按钮似乎都按照我的预期工作。
但是,
didSet
仅适用于“无绑定按钮”按钮。 “Button With Binding”按钮永远不会调用 didSet
。
显然,
tapCount
is正在从“Button With Binding”更新。当我点击几次然后点击“无绑定按钮”时,tapCount
从之前的值正确递增。
为什么绑定中没有调用
didSet
?如果没有 didSet
,您如何确认绑定确实一路流回源?
您不能将
didSet
用于像 @State
这样的属性包装器,但您可以在自定义结构中使用它,例如
struct Content {
var tapCount: Int = 0 {
didSet{
print("didSet tapCount = \(tapCount)")
}
}
// its nice to make funcs for testable logic
mutating func increment() {
tapCount += 1
}
}
struct Tapper: View {
@Binding var incrementMe: Int
var body: some View {
Button("Button With Binding") {
incrementMe += 1
}
}
}
struct ContentView: View {
@State private var content = Content()
var body: some View {
VStack {
Text("tapCount: \(content.tapCount)")
Tapper(incrementMe: $content.tapCount)
.padding(4.0)
Button("Button Without Binding") {
content.increment()
}
}
.padding()
}
}