Change Round Rect Button background color on StateHighlighted

17,763

Solution 1

[mBtn setTintColor:[UIColor grayColor]];

This only effects the highlighted state, so I believe that this is what you're looking for.

You can also set it from Interface Builder, from the Highlight Tint drop-down menu.

Solution 2

I'm replying to this old thread because it pops up consistently in searches for a solution to this problem and I have seen no solution elsewhere. It is truly annoying that setTintColor only applies to the highlighted state of a UIButton. Six months ago, it was equally annoying that it applied only to iOS 5, but that will hopefully be less of an issue going forward. With that in mind, I've drawn upon and combined a number of community suggestions to composite a general purpose solution to tinting a group of buttons in their normal state.

The method below accepts an NSArray of UIButtons and a set of color specifications as input. It applies the color specifications to one button using setTintColor, renders the result to a UIImage, and applies that image as the background image of the entire set of buttons. This avoids the need to create discrete image files for button colors. Also, it does so using a stretchable image so that it may work with a collection of buttons of different sizes (though note that it assumes the default corner rounding factors of UIButton). I hope you'll find it useful for iOS 5 targets.

- (void) setColorOfButtons:(NSArray*)buttons red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha {

    if (buttons.count == 0) {
        return;
    }

    // get the first button
    NSEnumerator* buttonEnum = [buttons objectEnumerator];
    UIButton* button = (UIButton*)[buttonEnum nextObject];

    // set the button's highlight color
    [button setTintColor:[UIColor colorWithRed:red/255.9999f green:green/255.9999f blue:blue/255.9999f alpha:alpha]];

    // clear any existing background image
    [button setBackgroundImage:nil forState:UIControlStateNormal];

    // place the button into highlighted state with no title
    BOOL wasHighlighted = button.highlighted;
    NSString* savedTitle = [button titleForState:UIControlStateNormal];
    [button setTitle:nil forState:UIControlStateNormal];
    [button setHighlighted:YES];

    // render the highlighted state of the button into an image
    UIGraphicsBeginImageContext(button.layer.frame.size);
    CGContextRef graphicsContext = UIGraphicsGetCurrentContext();
    [button.layer renderInContext:graphicsContext];
    UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
    UIImage* stretchableImage = [image stretchableImageWithLeftCapWidth:12 topCapHeight:0];
    UIGraphicsEndImageContext();

    // restore the button's state and title
    [button setHighlighted:wasHighlighted];
    [button setTitle:savedTitle forState:UIControlStateNormal];

    // set background image of all buttons
    do {
        [button setBackgroundImage:stretchableImage forState:UIControlStateNormal];
    } while (button = (UIButton*)[buttonEnum nextObject]);    
}

Solution 3

Just for people that will land here like I did when searching for changing background colors for highlighted state...

I ended up with an UIButton subclass that has a property for backgroundHighlightColor and tracks highlighting through KVO. Here's the link to GitHub: SOHighlightButton

You should be able to adapt it to any other scenario if you need more / other properties ot the UIButton to change if highlighted.

Share:
17,763
Syntax
Author by

Syntax

Updated on June 12, 2022

Comments

  • Syntax
    Syntax almost 2 years

    I'm trying to change the background color of a button when it's selected and don't want to use an image.

    [mBtn setBackgroundColor:[UIColor grayColor] forState:UIControlStateHighlighted];
    

    Any thoughts?

  • Syntax
    Syntax over 12 years
    This doesn't work, I get 'UIButton' may not respond to '-setTintColor:' 'UIButton' may not respond to 'setTintColor:'
  • Syntax
    Syntax over 12 years
    Thats a bit silly then, having to load an image just for a color change.
  • Ishu
    Ishu over 12 years
    @syntax Sorry bro then you have no option.
  • antalkerekes
    antalkerekes over 12 years
    You are right, I checked again, and this only works for iOS 5.0 and later. In this case, you will have to create a UIView, set its background color, and use this view as the background image for the highlighted state.
  • Admin
    Admin over 11 years
    please note that [button titleForState:UIControlStateNormal] may return invalid object when it's not set (e.g. when working through IB), for me changing this line to NSString savedTitle = [button titleLabel].text; works, so you might want to add a check although I am not sure exactly what check should be there (because it does NOT return nil, it returns an INVALID object and crashes if title is not set)