After reviewing all the responses (thank you), the problem seems to be that, without adding the (Bool) in
provided by the .onEditingChanged
closure, the true .onEditingChanged
closure is not being called. The fix with the shortest code is to use:
Slider(value: $value2) { _ in print("Slider 2 updating ") }
But then what is being called isn't entirely clear either. One of the Slider's declarations is:
nonisolated public init<V>(value: Binding<V>, in bounds: ClosedRange<V> = 0...1, @ViewBuilder label: () -> Label, @ViewBuilder minimumValueLabel: () -> ValueLabel, @ViewBuilder maximumValueLabel: () -> ValueLabel, onEditingChanged: @escaping (Bool) -> Void = { _ in }) where V : BinaryFloatingPoint, V.Stride : BinaryFloatingPoint
where there are several @ViewBuilder
parameters with closures as candidates - it could think it's redrawing: Label
, minimumValueLabel
, or maximumValueLabel
(which all seem unnecessary to redraw too), but I figured that without my closure 'returning' a Label
or ValueLabel
, as required for those other parameter closures respectively, the compiler would eliminate those as candidates, as only the .onEditingChanged
closure returns a Void
, which is what my closure was returning. Now I'm not sure which it thinks my closure is? In any case, adding the Bool with " _ in" at the start of my closure distinguishes it most clearly as meant for the .onEditingChanged
parameter specifically.
I also learned from Swift docs that if any @State
property changes, if the compiler can't be sure of what all that might effect, then it redraws *everything*, sometimes twice, as if it's look for what all changed.
In the end, not being sure of exactly how to properly implement Slider's .onEditingChanged
functionality in my own slider, I'm just going to use a .onChange(of: value2){}
modifier to ensure that multiple entire closures aren't being re-executed when only one slider is moved.
.