Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UISegmentedControl unselect segment by pressing it again

How can one unselect a given segment in a UISegmented control, by pressing the same segment again?

E.g. Press segment 0, it becomes selected and remains highlighted. Press segment 0 again and it becomes unselected and unhighlighted.

The control only fires UIControlEventValueChanged events. Other events don't seem to work with it.

There is a property 'momentary' which when set to YES almost allows the above behavior, excepting that highlighting is only momentary. When momentary=YES pressing the same segment twice results in two UIControlEventValueChanged events, but when momentary=NO only the first press of a given segment results in a UIControlEventValueChanged event being fired. I.e. subsequent presses on the same segment will not fire the UIControlEventValueChanged event.

like image 680
bhartsb Avatar asked Oct 27 '25 12:10

bhartsb


1 Answers

you can subclass UISegmentedControl:

Swift 3

class ReselectableSegmentedControl: UISegmentedControl {

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let previousSelectedSegmentIndex = self.selectedSegmentIndex

        super.touchesEnded(touches, withEvent: event)

        if previousSelectedSegmentIndex == self.selectedSegmentIndex {
            if let touch = touches.first {
                let touchLocation = touch.locationInView(self)
                if CGRectContainsPoint(bounds, touchLocation) {
                    self.sendActionsForControlEvents(.ValueChanged)
                }
            }
        }
    }


}

Swift 4

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    let previousSelectedSegmentIndex = self.selectedSegmentIndex

    super.touchesEnded(touches, with: event)

    if previousSelectedSegmentIndex == self.selectedSegmentIndex {
        let touch = touches.first!
        let touchLocation = touch.location(in: self)
        if bounds.contains(touchLocation) {
            self.sendActions(for: .valueChanged)
        }
    }
}

and then

 @IBAction func segmentChanged(sender: UISegmentedControl) {
    if (sender.selectedSegmentIndex == selectedSegmentIndex) {
        sender.selectedSegmentIndex =  UISegmentedControlNoSegment;
        selectedSegmentIndex = UISegmentedControlNoSegment;
    }
    else {
        selectedSegmentIndex = sender.selectedSegmentIndex;
    }
}
like image 123
protspace Avatar answered Oct 29 '25 02:10

protspace



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!