UISegmentedControl selected segment color

Here is the absolute simplest way to change the selected segment to any RGB color. No subclassing or hacks required.

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;

UIColor *newTintColor = [UIColor colorWithRed: 251/255.0 green:175/255.0 blue:93/255.0 alpha:1.0];
    segmentedControl.tintColor = newTintColor;

UIColor *newSelectedTintColor = [UIColor colorWithRed: 0/255.0 green:175/255.0 blue:0/255.0 alpha:1.0];
[[[segmentedControl subviews] objectAtIndex:0] setTintColor:newSelectedTintColor];

This example shows the important steps:

  1. Sets the control style to "StyleBar", which is required for it to work
  2. Sets the un-selected color for the entire control first to orange
  3. Sets the color of the selected segment to green

Notes:

  • Steps 1 and 2 can be done in interface builder, or in code as shown. However step 3 can only be done in code
  • The color values being set with notation like this "123.0/255.0" is just a way to make the RGB values stand out instead the normalized float values required by UIColor (just ignore it if you like)

I found A Simple Way to Add Color for Selected Segment in UISegmentcontrol

sender is UISegmentControl

for (int i=0; i<[sender.subviews count]; i++) 
{
    if ([[sender.subviews objectAtIndex:i]isSelected] ) 
    {               
    UIColor *tintcolor=[UIColor colorWithRed:127.0/255.0 green:161.0/255.0 blue:183.0/255.0 alpha:1.0];
    [[sender.subviews objectAtIndex:i] setTintColor:tintcolor];
    }
   else 
    {
        [[sender.subviews objectAtIndex:i] setTintColor:nil];
    }
}

Check its Working For Me


To do this you simply have to find the selected segment, for example by iterating over the segmented control's subviews and testing the isSelected property, then simply call the setTintColor: method on that subview.

I did this by connecting an action to each segmented control on the ValueChanged event in Interface Builder, I connected them to this this method in the view controller file which is essentially msprague's answer:

- (IBAction)segmentedControlValueChanged:(UISegmentedControl*)sender
{
    for (int i=0; i<[sender.subviews count]; i++)
    {
        if ([[sender.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && [[sender.subviews objectAtIndex:i]isSelected])
        {
            [[sender.subviews objectAtIndex:i] setTintColor:[UIColor whiteColor]];
        }
        if ([[sender.subviews objectAtIndex:i] respondsToSelector:@selector(isSelected)] && ![[sender.subviews objectAtIndex:i] isSelected])
        {
            [[sender.subviews objectAtIndex:i] setTintColor:[UIColor blackColor]];
        }
    }
}

To ensure that the control is displayed correctly each time the view is opened by the user I also had to override the -(void)viewDidAppear:animated method and call the method as follows:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    //Ensure the segmented controls are properly highlighted
    [self segmentedControlValueChanged:segmentedControlOne];
    [self segmentedControlValueChanged:segmentedControlTwo];
}

For some bonus points if you do want to set the segmented control to use a white tint color on selection then you will also want to change the color of the text to black when it's selected, you can do this like so:

//Create a dictionary to hold the new text attributes
NSMutableDictionary * textAttributes = [[NSMutableDictionary alloc] init];
//Add an entry to set the text to black
[textAttributes setObject:[UIColor blackColor] forKey:UITextAttributeTextColor];
//Set the attributes on the desired control but only for the selected state
[segmentedControlOne setTitleTextAttributes:textAttributes forState:UIControlStateSelected];

With the introduction of iOS 6 setting the tint color of the selected item for the first time in the viewDidAppear method wont work, to get around this I used grand central dispatch to change the selected color after a fraction of a second like so:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        [self segmentedControlValueChanged:segmentedControlOne];
    });

For some reason Apple dont allow you to change the color of standard UISegmentedControls.

There is however a "legal" way around it which is to change the segmented control style to UISegmentedControlStyleBar. This makes it look slightly different which you may not like but it does allow color.

    NSArray *itemArray = [NSArray arrayWithObjects: @"One", @"Two", @"Three", nil];
UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:itemArray];

//Change Bar Style and ad to view then release segmented controller

segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;
segmentedControl.tintColor = [UIColor colorWithRed:.9 green:.1 blue:.1 alpha:1]; 
[self.view addSubview:segmentedControl];
[segmentedControl release];

Hope this helped,

Seb Kade "I'm here to help"