By dubbeat


2010-05-11 07:49:58 8 Comments

This one has me stumped.

Is it possible at all to change the background color of a UIButton in Cocoa for iPhone. I've tried setting the background color but it only changes the corners. setBackgroundColor: seems to be the only method available for such things.

[random setBackgroundColor:[UIColor blueColor]];
[random.titleLabel setBackgroundColor:[UIColor blueColor]];

16 comments

@gheese 2012-10-17 17:20:58

You can also add a CALayer to the button - you can do lots of things with these including a color overlay, this example uses a plain color layer you can also easily graduate the colour. Be aware though added layers obscure those underneath

+(void)makeButtonColored:(UIButton*)button color1:(UIColor*) color
{

    CALayer *layer = button.layer;
    layer.cornerRadius = 8.0f;
    layer.masksToBounds = YES;
    layer.borderWidth = 4.0f;
    layer.opacity = .3;//
    layer.borderColor = [UIColor colorWithWhite:0.4f alpha:0.2f].CGColor;

    CAGradientLayer *colorLayer = [CAGradientLayer layer];
    colorLayer.cornerRadius = 8.0f;
    colorLayer.frame = button.layer.bounds;
    //set gradient colors
    colorLayer.colors = [NSArray arrayWithObjects:
                         (id) color.CGColor,
                         (id) color.CGColor,
                         nil];

    //set gradient locations
    colorLayer.locations = [NSArray arrayWithObjects:
                            [NSNumber numberWithFloat:0.0f],
                            [NSNumber numberWithFloat:1.0f],
                            nil];


    [button.layer addSublayer:colorLayer];

}

@Valeriy Van 2013-06-26 19:22:49

Brilliant!!!!!! But couldn't be called several times against same button. Could, but new layers are added again and again.

@mafso 2014-10-19 19:59:37

@StanJames: Edits to code should be suggested by a comment (or, if appropriate, by your own answer).

@pawurb 2017-06-09 15:06:10

Swift 3:

        static func imageFromColor(color: UIColor, width: CGFloat, height: CGFloat) -> UIImage {
            let rect = CGRect(x: 0, y: 0, width: width, height: height);
            UIGraphicsBeginImageContext(rect.size)
            let context = UIGraphicsGetCurrentContext()!
            context.setFillColor(color.cgColor)
            context.fill(rect)
            let img = UIGraphicsGetImageFromCurrentImageContext()!
            UIGraphicsEndImageContext()
            return img;
        }

        let button = UIButton(type: .system)
        let image = imageFromColor(color: .red, width: 
        button.frame.size.width, height: button.frame.size.height)
        button.setBackgroundImage(image, for: .normal)

@Michael Dautermann 2017-06-11 06:45:56

This would be a much more useful answer if you said how to invoke or make use of the code you've put up there. Does it go into a UIButton extension?

@pawurb 2017-06-13 08:01:24

@MichaelDautermann added usage example

@Vinicius Carvalho 2016-03-30 19:24:55

[myButton setBackgroundColor:[UIColor blueColor]]; [myButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

It's possible change this way or going on Storyboard and change background on options in right side.

@DonnaLea 2015-11-09 22:13:49

I know this was asked a long time ago and now there's a new UIButtonTypeSystem. But newer questions are being marked as duplicates of this question so here's my newer answer in the context of an iOS 7 system button, use the .tintColor property.

let button = UIButton(type: .System)
button.setTitle("My Button", forState: .Normal)
button.tintColor = .redColor()

@zmonteca 2015-03-17 16:59:13

Per @EthanB suggestion and @karim making a back filled rectangle, I just created a category for the UIButton to achieve this.

Just drop in the Category code: https://github.com/zmonteca/UIButton-PLColor

Usage:

[button setBackgroundColor:uiTextColor forState:UIControlStateDisabled];

Optional forStates to use:

UIControlStateNormal
UIControlStateHighlighted
UIControlStateDisabled
UIControlStateSelected

@SMSidat 2013-12-30 12:33:45

This isn't as elegant as sub-classing UIButton, however if you just want something quick - what I did was create custom button, then a 1px by 1px image with the colour I'd want the button to be, and set the background of the button to that image for the highlighted state - works for my needs.

@Stian Storrvik 2011-04-05 14:00:26

This can be done programmatically by making a replica:

    loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [loginButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    loginButton.backgroundColor = [UIColor whiteColor];
    loginButton.layer.borderColor = [UIColor blackColor].CGColor;
    loginButton.layer.borderWidth = 0.5f;
    loginButton.layer.cornerRadius = 10.0f;

edit: ofcourse, you'd have to #import <QuartzCore/QuartzCore.h>

edit: to all new readers, you should also consider a few options added as "another possibility". for you consideration.

As this is an old answer, I strongly recommend reading comments for troubleshooting

@pankaj 2011-04-23 12:11:25

i tried your code but it didnt work for me

@Stian Storrvik 2011-04-24 20:41:32

didn't work, or didn't you get the expected result?

@user470069 2011-05-21 03:53:48

Best answer yet quartz FTW

@Steven 2011-10-07 05:33:01

This is what the OP is looking for.

@daver 2011-12-01 03:17:14

sweet! Of all the solns I found this is the one I went with. As a point of clarification, making a 'replica' means using Quartz to draw a rounded rectangle in a custom button, rather than using a RoundedRect-type button. At first I thought it meant somehow making a duplicate of a rounded rect with a different color to simulate changing the bg color.

@Bram 2012-03-21 16:35:07

Worked perfectly, best answer to OP. Thanks for sharing.

@Polly 2012-08-11 11:05:18

@daver: This answer is so popular it must have merit I am missing. How can one change the background colour according to state? Presumably one must explicitly change background colour every time the state changes. My button is disabled on press until a web service responds. Must I change to highlight colour on press and have a timer change to disabled colour while waiting for the ws to respond? If I am missing the point can someone please explain. Thanks Polly.

@owen gerig 2012-08-16 18:26:46

FYI for others take note of UIButtonTypeCustom, this wont work on default style buttons.

@AlvinfromDiaspar 2012-08-27 14:54:45

Does this need to be updated? The snippet posted does not make a buttons background content to be of any color (only the edges).

@Stian Storrvik 2012-08-31 15:05:35

sorry for not answering in a long time; Polly: you have to do some custom design here, but this is the outline that you can use. for you specific use-case, you should experiment and see what works best imo. @AlvinfromDiaspar: you swap out the "whitecolor" with whichever color you want. Use RGB to create the color you want if it's not standard. hope this helps.

@Wayne Shelley 2013-04-11 15:28:33

Also needs to be set as UIButtonTypeCustom in the xib file. Changing it programmatically doesn't seem to work. Please update the post if possible as these comments are not very visible.

@mmm 2013-06-18 19:48:28

I do not get the expected result, as the background image goes green and instantly stays the original color. How can I permanently change the color and only remove when I want? Thanks

@daver 2013-08-13 02:25:14

@Polly: Sorry didn't see your comment sooner, but if you're still interested here's what I ended up doing: subclass UIButton and override drawRect: to draw the rounded rect using some UIBezierPaths. After drawing, fill it with a gradient using CGGradientCreateWithColorComponents(). One of the args to this function is a 4 element array of floats (corresponding to R, G, B, & alpha). I defn'ed 2 color arrays, one for each state, and chose the appropriate one in drawRect based on the button state.

@RndmTsk 2015-06-29 19:01:21

The important thing to note is that layer.borderColor takes a CGColor, not a UIColor! Therefore you cannot add it as a dynamic property in the identity inspector - unlike layer.cornerRadius and layer.borderWidth

@Daniel Springer 2018-07-30 07:34:11

.backgroundColor was all I needed

@wubbe 2012-02-24 14:40:33

Another possibility:

  1. Create a UIButton in Interface builder.
  2. Give it a type 'Custom'
  3. Now, in IB it is possible to change the background color

However, the button is square, and that is not what we want. Create an IBOutlet with a reference to this button and add the following to the viewDidLoad method:

[buttonOutlet.layer setCornerRadius:7.0f];
[buttonOutlet.layer setClipToBounds:YES];

Don't forget to import QuartzCore.h

@iforce2d 2012-05-15 18:30:31

Perfect, thank you! I'm not sure if it's because of the iOS version I'm using (5.1) but setClipToBounds was not available. Instead I used buttonOutlet.layer.masksToBounds = TRUE;

@Will 2013-02-05 18:41:49

When I add this code, it shows a rounded rect, but when i click on it, the button does not reverse highlight. What is going on?

@ch3rryc0ke 2013-06-25 01:24:29

The problem with this approach is that you can't set a background color for the highlighted state of the button.

@Ahmet Ardal 2012-06-15 10:46:38

For professional and nice looking buttons, you may check this custom button component. You can use it directly in your views and tableviews or modify the source code to make it meet your needs. Hope this helps.

@wubbe 2012-04-17 08:18:35

Another possibility (the best and most beautiful imho):

Create a UISegmentedControl with 2 segments in the required background color in Interface Builder. Set the type to 'bar'. Then, change it to having only one segment. Interface builder does not accept one segment so you have to do that programmatically.

Therefore, create an IBOutlet for this button and add this to the viewDidLoad of your view:

[segmentedButton removeSegmentAtIndex:1 animated:NO];

Now you have a beautiful glossy, colored button with the specified background color. For actions, use the 'value changed' event.

(I have found this on http://chris-software.com/index.php/2009/05/13/creating-a-nice-glass-buttons/). Thanks Chris!

@Mugunth 2012-05-20 01:37:55

Subclass UIButton and override setHighlighted and setSelected methods

-(void) setHighlighted:(BOOL)highlighted {

  if(highlighted) {
    self.backgroundColor = [self.mainColor darkerShade];
  } else {
    self.backgroundColor = self.mainColor;
  }
  [super setHighlighted:highlighted];
}

-(void) setSelected:(BOOL)selected {

  if(selected) {
    self.backgroundColor = [self.mainColor darkerShade];
  } else {
    self.backgroundColor = self.mainColor;
  }
  [super setSelected:selected];
}

My darkerShade method is in a UIColor category like this

-(UIColor*) darkerShade {

  float red, green, blue, alpha;
  [self getRed:&red green:&green blue:&blue alpha:&alpha];

  double multiplier = 0.8f;
  return [UIColor colorWithRed:red * multiplier green:green * multiplier blue:blue*multiplier alpha:alpha];
}

@karim 2012-02-17 11:53:09

I have a different approach,

[btFind setTitle:NSLocalizedString(@"Find", @"") forState:UIControlStateNormal];    
[btFind setBackgroundImage:[CommonUIUtility imageFromColor:[UIColor cyanColor]] 
        forState:UIControlStateNormal];
btFind.layer.cornerRadius = 8.0;
btFind.layer.masksToBounds = YES;
btFind.layer.borderColor = [UIColor lightGrayColor].CGColor;
btFind.layer.borderWidth = 1;

From CommonUIUtility,

+ (UIImage *) imageFromColor:(UIColor *)color {
    CGRect rect = CGRectMake(0, 0, 1, 1);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    //  [[UIColor colorWithRed:222./255 green:227./255 blue: 229./255 alpha:1] CGColor]) ;
    CGContextFillRect(context, rect);
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

Don't forget to #import <QuartzCore/QuartzCore.h>

@DefenestrationDay 2012-02-27 22:05:58

Nice one. I found I had to add a btFind.layer.borderWidth = 1;

@Stephan 2012-04-11 09:37:12

I like this solution, but at the moment I can't use it. I get an error, because "CommonUIUtility" can't be found. Google just gives me eclipse stuff, but i guess it should be in the QuartzCore? Any ideas?

@karim 2012-04-15 09:24:24

No, that's a user defined class for doing common UI stuffs in the app. You write the imageFromColor method in you own class.

@Adam Waite 2013-03-28 17:23:33

Cripes, that was harder than it should have been. Thanks for a great solution.

@EthanB 2013-08-20 16:34:28

Smells like a category method on UIButton: setBackgroundColor:(UIColor *) forState:(UIControlState).

@dmur 2013-10-03 00:21:22

It's so silly that we're on iOS 7 and this is STILL the cleanest way to add a background color

@Shaun 2011-10-13 20:16:29

add a second target for the UIButton for UIControlEventTouched and change the UIButton background color. Then change it back in the UIControlEventTouchUpInside target;

@Jacob Jennings 2011-11-22 22:07:13

colored UIButton

If you are not wanting to use images, and want it to look exactly like the Rounded Rect style, try this. Just place a UIView over the UIButton, with an identical frame and auto resize mask, set the alpha to 0.3, and set the background to a color. Then use the snippet below to clip the rounded edges off the colored overlay view. Also, uncheck the 'User Interaction Enabled' checkbox in IB on the UIView to allow touch events to cascade down to the UIButton underneath.

One side effect is that your text will also be colorized.

#import <QuartzCore/QuartzCore.h>

colorizeOverlayView.layer.cornerRadius = 10.0f;
colorizeOverlayView.layer.masksToBounds = YES;

@stigi 2010-05-11 08:52:41

I assume you're talking about a UIButton with UIButtonTypeRoundedRect? You can't change the background color of that. When you try changing it's background color you're rather changing the color of the rect the button is drawn on (which is usually clear). So there are two ways to go. Either you subclass UIButton and overwrite its -drawRect: method or you create images for the different button states (which is perfectly fine to do).

If you set the background images in Interface Builder you should notice that IB doesn't support setting images for all the states the button can have, so I recommend setting the images in code like this:

UIButton *myButton = [UIButton buttonWithType:UIButtonTypeCustom];
[myButton setBackgroundImage:[UIImage imageNamed:@"normal.png"] forState:UIControlStateNormal];
[myButton setBackgroundImage:[UIImage imageNamed:@"disabled.png"] forState:UIControlStateDisabled];
[myButton setBackgroundImage:[UIImage imageNamed:@"selected.png"] forState:UIControlStateSelected];
[myButton setBackgroundImage:[UIImage imageNamed:@"higligted.png"] forState:UIControlStateHighlighted];
[myButton setBackgroundImage:[UIImage imageNamed:@"highlighted+selected.png"] forState:(UIControlStateHighlighted | UIControlStateSelected)];

The last line shows how to set an image for the selected & highlighted state (that's the one IB can't set). You don't need the selected images (line 4 & 6) if you're button dosn't need a selected state.

@dubbeat 2010-05-11 09:37:17

Thanks for explanation. Just a quick question. If I'm overwriting the drawrect method I guess that would involve me using a drawing library? Something alone the lines of programmatically drawing a rounded rectangle and filling it with a color?

@stigi 2010-05-11 09:53:47

I just did a short google query for "iphone drawrect round corners" and found this: iphonedevelopment.blogspot.com/2008/11/… Check the drawrect method for an example how to draw a round rect. You can use CGContextSetFillColorWithColor and CGContextFillPath to fill the path drawn by CGContextAddArcToPoint.

@dubbeat 2010-05-11 10:17:34

Thats great. Thanks a lot

@NSTJ 2014-05-21 08:22:52

+50 for pointing out the bitmasking potential for control states, i.e.: forState:(UIControlStateHighlighted | UIControlStateSelected) Cheers.

@dubbeat 2010-05-11 08:26:51

Well I'm 99% percent positive that you cannot just go and change the background color of a UIButton. Instead you have to go and change the background images yourself which I think is a pain. I'm amazed that I had to do this.

If I'm wrong or if theres a better way without having to set background images please let me know

[random setBackgroundImage:[UIImage imageNamed:@"toggleoff.png"] forState:UIControlStateNormal];
    [random setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];


[random setBackgroundImage:[UIImage imageNamed:@"toggleon.png"] forState:UIControlStateNormal];
    [random setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

@Henley Chiu 2011-08-07 17:00:42

You're absolutely right. It is a pain, and something that should take a few mins to do instead of the hassle of creating images. Plus if your button is round, it makes it even harder to do as well... Such a pain.

Related Questions

Sponsored Content

17 Answered Questions

[SOLVED] UITableViewHeaderFooterView: Unable to change background color

33 Answered Questions

[SOLVED] How do I create a basic UIButton programmatically?

32 Answered Questions

[SOLVED] Can I embed a custom font in an iPhone application?

  • 2008-12-11 20:21:11
  • Airsource Ltd
  • 233045 View
  • 750 Score
  • 32 Answer
  • Tags:   ios cocoa-touch fonts

10 Answered Questions

[SOLVED] How to set the title of UIButton as left alignment?

  • 2010-05-04 11:56:19
  • Madan Mohan
  • 185585 View
  • 426 Score
  • 10 Answer
  • Tags:   objective-c uibutton

3 Answered Questions

[SOLVED] How to change the background color of a button?

  • 2013-11-20 13:18:38
  • Adam
  • 703 View
  • 0 Score
  • 3 Answer
  • Tags:   ios iphone

5 Answered Questions

6 Answered Questions

[SOLVED] how to Change a Rounded Rect UIbutton background color

3 Answered Questions

[SOLVED] change UITableViewCell background color when selected

  • 2010-10-28 12:47:40
  • Manal
  • 1968 View
  • 0 Score
  • 3 Answer
  • Tags:   iphone

2 Answered Questions

[SOLVED] background color of uiactionsheet

1 Answered Questions

colorizing UIbuttons

Sponsored Content