I'm trying to fix a small bug. I have an UISegmentedControl
that stays showing user interaction if I navigate back while pressing a segment (without releasing the finger which is selecting the segment from the screen):
I tried to deselect the segment on viewWillDisappear
but I doesn't make a difference. Any ideas on how to reset the state of the UISegmentedControl
?
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
fixedPositionSegmentControl.selectedSegmentIndex = UISegmentedControl.noSegment
fixedPositionSegmentControl.selectedSegmentIndex = 0
}
The problem is that in this specific case (leaving the screen while touching the control) the segmented control's touchesEnded
/ touchesCancelled
functions do not get called. So you could cancel the touch programmatically:
override func viewDidDisappear(_ animated: Bool) {
segmentedControl.touchesCancelled(Set<UITouch>(), with: nil)
super.viewDidDisappear(animated)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
segmentedControl.selectedSegmentIndex = 0
}
Subclassing UISegmentedControl
might even be the cleaner (but maybe oversized) approach:
class SegmentedControl: UISegmentedControl {
// property to store the latest touches
private var touches: Set<UITouch>?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
self.touches = touches
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
self.touches = touches
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
self.touches = nil
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
self.touches = nil
}
override func didMoveToWindow() {
// cancel pending touches when the view is removed from the window
if window == nil, let touches = touches {
touchesCancelled(touches, with: nil)
}
}
}
With that approach you can simply reset the index in viewWillAppear
:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
segmentedControl.selectedSegmentIndex = 0
}