18

I have a UISegmentedControl with two segments (index: 0 and 1) that I am trying to reset programmatically to 0. When I run the command below it does not reset the segment index to 0 as expected. Instead it highlights segment indexed 1.

    [seg setSelectedSegmentIndex:0];

Oddly when I log the selected segment, it returns 0.

    NSLog(@"seg setSelectedSegmentIndex %d", seg.selectedSegmentIndex); 

Also oddly, after running setSelectedSegmentIndex:0 I cannot reselect segment 0 manually by touch, it seems to be locked to segment 1, until I tap 1 wherein it works as normal.

Here is the setup for the button:

    itemArray = [NSMutableArray arrayWithObjects: @"Zero", @"One", nil];
    seg = [[UISegmentedControl alloc] initWithItems:itemArray];
    [seg setFrame:segRect];
    seg.segmentedControlStyle = UISegmentedControlStyleBar;
    seg.momentary = NO;
    [seg addTarget:self action:@selector(someAction:) forControlEvents: UIControlEventValueChanged];
    [mainView addSubview:seg];

NOTE: To restate what I was trying to accomplish with this question: I want to set a UISegmentedControl's selected index via a variable dynamically, get the appropriate visual feedback, and check the selected index in a method, to make something happen depending on the selected index. See my answer below for a solution.

Cœur
  • 37,241
  • 25
  • 195
  • 267
OWolf
  • 5,012
  • 15
  • 58
  • 93
  • are both the segments enabled before you try to select? (using isEnabledForSegmentAtIndex) – Nitin Alabur Jan 24 '13 at 05:48
  • @calvinBhai I think so, wouldn't the default be enabled? – OWolf Jan 24 '13 at 07:49
  • I have the same issue, segment 0 cannot be reselected once one of the others have been. I am going to release with a workaround of having a blank seg 0 for now. My segment is inside a UIControl inside a UIScrollView. I had the problem previously when iOS 5 worked fine, but the same binary on iOS6 exhibited this issue. – Nick T Jan 24 '13 at 15:22
  • @NickThorne yeah, seems like should be fixable. That is: to do programatically what happens when the view is tapped. I'll add it here if I figure it out. – OWolf Jan 24 '13 at 16:00
  • i know it should be default, that was a "just in case". is the segment being added to the view in viewDidLoad or in the viewWill/DidAppear? (there is a good chance that setSelectedSegmentIndex will work better after the view is loaded) – Nitin Alabur Jan 24 '13 at 16:32
  • @calvinBhai thanks. Yes, it it. I will post here when I figure it out. – OWolf Jan 24 '13 at 17:05
  • I just posted an answer below - my issue is with Interface Builder.. – Nick T Jan 25 '13 at 19:43

7 Answers7

30

Change in viewDidLoad:

[seg setSelectedSegmentIndex:index];

you change use the index value as your wish.

Krishnan8190
  • 320
  • 2
  • 8
2

From code, you can just do seg.selectedSegmentIndex = someDefaultIndex.

Whether you should set it in viewDidLoad: or not depends entirely on the structure of your application. For example, if your app is starting up and loading the view for the first time and needs to set the control to whatever value it had during the previous run of the app, then it definitely makes sense to do it there.

NewStack
  • 990
  • 8
  • 19
2

Swift 3.0

segmentedControl.selectedSegmentIndex = #your value#
Abhishek Jain
  • 4,557
  • 2
  • 32
  • 31
2

The correct answer is the @arcady bob one at this link. I have posted an updated version for Swift 5, which I quote here:

yourSegmentedControl.selectedSegmentIndex = 0

yourSegmentedControl.sendActions(for: UIControl.Event.valueChanged)

If you use just the first line, the segmented will react accordingly graphically, but your IBAction associated with the segmented control won't be called. In a few words: the second line is like tapping on the segmented control. This is what I needed and what I was missing.

EmmettBrown88
  • 148
  • 1
  • 2
  • 13
1

This helps sort the selected segment, in terms of the visual feedbak, that is after programatically setting the selected segment this will tint the segments properly.

for (int i=0; i<[seg.subviews count]; i++)
{

    if ([[seg.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && [[seg.subviews objectAtIndex:i]isSelected])
    {
        [[seg.subviews objectAtIndex:i] setTintColor:[UIColor grayColor]];
    }
    if ([[seg.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && ![[seg.subviews objectAtIndex:i] isSelected])
    {
        [[seg.subviews objectAtIndex:i] setTintColor:[UIColor blackColor]];
    }
}
OWolf
  • 5,012
  • 15
  • 58
  • 93
0

To restate what I was trying to accomplish with this question: I want to set a UISegmentedControl's selected index via a variable dynamically, get the appropriate visual feedback, and check the selected index in a method, to make something happen depending on the selected index.

Originally I guessed that this is as simple as: mySegmentedController.selectedSegmentIndex = someIndex, then test for the index. But as stated in my question, it was not working for me. The behavior is odd. After running that code the appropriate button would not highlight.

Here is a project where I did fix it, so it works. Not sure exactly why it works. Possibly a delay I put in there, before setting the index. I will update and comment the project file if I can refine it.

http://owolf.net/uploads/StackOverflow/SegmentedControllers.zip

OWolf
  • 5,012
  • 15
  • 58
  • 93
0

WARNING: This is not quite answering the question, but is closely related.

I had a similar issue. Most of the time my UISegmentedController worked fine. It has 4 segments, Off, 30, 60 and 120.

At random intervals (normally just prior to a release!!), the Off segment becomes un-selectable from the user interface. (I didn't try selecting it from code because that is not what I need to do and won't solve my problem.)

The solution is to delete that UISegmentedController from my XIB and replace it with a fresh (and exactly identical) one which then works fine.

I even CMD-C and CMD-V'd the offending UISegmentedController into another App's XIB. And the Off segment (i.e the one at index 0) was un-selectable in that XIB too.

This seems to be an issue with XCode.

Nick T
  • 897
  • 8
  • 30