I have a SwiftUI Form I'm working with, which updates values of an EnvironmentObject. I need to call a function when the value of a Picker changes, but every way I've found is either really messy, or causes other problems. What I'm looking for is a similar way in which the Slider works, but there doesn't seem to be one. Basic code without any solution is here:
class ValueHolder : ObservableObject {
@Published var sliderValue : Float = 0.5
static let segmentedControlValues : [String] = ["one", "two", "three", "four", "five"]
@Published var segmentedControlValue : Int = 3
}
struct ContentView: View {
@EnvironmentObject var valueHolder : ValueHolder
func sliderFunction() {
print(self.valueHolder.sliderValue)
}
func segmentedControlFunction() {
print(ValueHolder.segmentedControlValues[self.valueHolder.segmentedControlValue])
}
var body: some View {
Form {
Text("\(self.valueHolder.sliderValue)")
Slider(value: self.$valueHolder.sliderValue, onEditingChanged: {_ in self.sliderFunction()
})
Text("\(ValueHolder.segmentedControlValues[self.valueHolder.segmentedControlValue])")
Picker("", selection: self.$valueHolder.segmentedControlValue) {
ForEach(0..<ValueHolder.segmentedControlValues.count) {
Text("\(ValueHolder.segmentedControlValues[$0])")
}
}.pickerStyle(SegmentedPickerStyle())
}
}
}
After reviewing this similar (but different) question here: Is there a way to call a function when a SwiftUI Picker selection changes? I have tried using onReceive() as below, but it is also called when the Slider value changes, resulting in unwanted behavior.
.onReceive([self.valueHolder].publisher.first(), perform: {_ in
self.segmentedControlFunction()
})
I have tried changing the parameter for onReceive to filter it by only that value. The value passed is correct, but the segmentedControlFunction still gets called when the slider moves, not just when the picker changes.
.onReceive([self.valueHolder.segmentedControlValue].publisher.first(), perform: {_ in
self.segmentedControlFunction()
})
How can I get the segmentedControlFunction to be called in a similar way to the sliderFunction?