54

in fact the title contains my question. I have a UISegmentedControl, and need to deselect currently selected tab. I tried:

[menu setSelectedSegmentIndex:-1];

menu being the UBOutlet for uisegmentedcontrol but this gives me exception. anyone have some idea? thanks peter

dusker
  • 846
  • 2
  • 8
  • 13
  • 8
    I'd also suggest using UISegmentedControlNoSegment instead of -1 - it's not a source of problem here but just in case – Vladimir Feb 05 '10 at 09:48
  • 2010-02-05 11:10:16.799 Gazetapl[30839:20b] *** -[NSCFArray length]: unrecognized selector sent to instance 0x3d39ed0 [Session started at 2010-02-05 11:10:16 +0100.] 2010-02-05 11:10:16.800 Gazetapl[30839:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFArray length]: unrecognized selector sent to instance 0x3d39ed0' 2010-02-05 11:10:16.802 Gazetapl[30839:20b] Stack: ( – dusker Feb 05 '10 at 10:10

8 Answers8

254

The right way to do this is:

[menu setSelectedSegmentIndex:UISegmentedControlNoSegment];

Edit:

Swift 5:

menu.selectedSegmentIndex = UISegmentedControl.noSegment
Calin Drule
  • 2,899
  • 1
  • 15
  • 12
  • 11
    I do not understand why OP does not select this answer!. – Ali Nov 10 '14 at 04:39
  • 1
    @Ali because this wasn't his question. He was already doing this (mostly) correctly. His problem was elsewhere as I explained. – David Kanarek Nov 17 '14 at 17:16
  • @DavidKanarek but it really doesn't make sense, this is the answer and I had the same problem, I googled it, this was the first google result, and this is the answer, strange, also in the question I can't see any other code or exceptions..! – Boda Sep 14 '15 at 07:14
32

Setting the segmentedControl to .momentary = YES changes the way the user can interact with the segmentedControl. If you want to have nothing selected initially when the page loads but have segmentedControl behave the same after a selection is made by the user then you will want something more like this:

Swift 4 solution:

 @IBOutlet weak var segmentedControl: UISegmentedControl!

 self.segmentedControl.selectedSegmentIndex = UISegmentedControlNoSegment

Swift 5.1:

 self.segmentedControl.selectedSegmentIndex = UISegmentedControl.noSegment
Vahid
  • 3,352
  • 2
  • 34
  • 42
Dan Leonard
  • 3,325
  • 1
  • 20
  • 32
31

I guess you try to create a momentary selection in segmented control. In interface builder set the segmentedcontrol to momentary. Or in code you can do:

menu.momentary = YES;
dombesz
  • 7,890
  • 5
  • 38
  • 47
  • Momentary will still result in a segment being selected on load. Besides, use of Momentary should only be because you actually want a Momentary segment control, not just to try to force no segment selection. Use the UISegmentedControlNoSegment solution. – Michael Peterson Apr 01 '16 at 20:28
8

I did class which supports this kind of interaction:

class UIDeselectableSegmentedControl: UISegmentedControl {

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

        super.touchesEnded(touches, with: event)

        if previousSelectedSegmentIndex == self.selectedSegmentIndex {

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

The main advantage of that is that you just need to modify which class the Storyboard/Xib/ViewCode is using and this will work like a charm ;]

RodolfoAntonici
  • 1,555
  • 21
  • 34
7

swift 4

@IBOutlet weak var segmentControl: UISegmentedControl! {
    didSet {
        segmentControl.selectedSegmentIndex = UISegmentedControl.noSegment
    }
}
3

You can now do this in xcode 6 in the interface builder:

Deselect the 'Selected' option under segmented control behaviour in attributes inspector.

Zaxter
  • 2,939
  • 3
  • 31
  • 48
2

The Swift solution: @IBOutlet weak var mySegmentedControl: UISegmentedControl! and mySegmentedControl.selectedSegmentIndex = -1.

Tom Daniel
  • 183
  • 1
  • 9
-1

I would assume that you've called [myArray length] instead of the proper [myArray count] somewhere in your code. NSArray uses the count method, not length for the number of items it contains.

David Kanarek
  • 12,611
  • 5
  • 45
  • 62
  • 3
    hi, i don't understand. what does this have to do with uisegmentedcontrol – dusker Feb 07 '10 at 21:17
  • 1
    Nothing directly, but based on the exception you posted, the problem is not with UISegementedControl. Perhaps somewhere in your handling of changing the selected segment you access an array. – David Kanarek Feb 08 '10 at 01:18
  • 4
    Why the down vote? Mine is the only answer that actually addresses the problem dusker was having. – David Kanarek Nov 17 '14 at 17:17
  • Actually, your answer does not address the question. The op wants to deselect a segment from a UISegmentedController. – Uzaak Dec 23 '15 at 14:18
  • 2
    The OP asked the wrong question (can be clearly seen by the exception), this is the correct answer. It addresses the problem 100%. – oyalhi Jan 16 '16 at 18:58
  • What a tangent. But I commend your insight. – carlossless Apr 01 '16 at 09:18
  • 2
    This doesn't answer the question of how to have no option selected at all...swift option below show be the accepted answer. – csmith Apr 28 '17 at 02:49