Here's an example that demonstrates what I'm seeing:
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 renders this:
"Button With Binding" is the button from the Tapper struct with the binding back to tapCount. "Button Without Binding" is the button from ContentView that increments tapCount directly (no binding). As far as the view is concerned both buttons appear to work exactly as I would expect.
However, didSet is only called for the "Button Without Binding" button. didSet is never called for the "Button With Binding" button.
Clearly, tapCount is being updated from "Button With Binding". When I tap it a few times and then tap "Button Without Binding" tapCount increments from its previous value correctly.
Why isn't didSet called from the binding? Without didSet how can you confirm that a binding is indeed flowing all the way back to the source?

Since the
Viewstruct is immutable you are really applying thedidSetto the property wrapper so it only works for that state wrapper and not any other wrappers like the binding one. So, you could just implementdidSetagain for your@Binding, e.g.To have the same code run in both
didSets you could simply call a func or to have exactly the same code path just move thetapCountinto a struct, e.g.