views:

24778

answers:

13

How can I set a custom background color of a button?

Interface Builder doesn't seem to have an interface to do this.

Is it only available programmatically? If so, can you provide an example, please?

A: 
keremk
This will not give you the nice rounded corners.
Bryan
A: 
subjective-c
+9  A: 

I found that I needed to use a stretchable image to accomplish this. Apple's UICatalog example has one or more colored buttons that are drawn in this fashion. You could use their template image and recolor it to suit your button needs.

I'm not sure about doing this in Interface Builder, but I was able to create a button and use an image for its contents using the following code:

downloadButton = [[UIButton alloc] initWithFrame:CGRectMake(36, 212, 247, 37)];

downloadButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
downloadButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

[downloadButton setTitle:NSLocalizedStringFromTable(@"Download", @"Localized", nil) forState:UIControlStateNormal]; 
[downloadButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[downloadButton setFont:[UIFont boldSystemFontOfSize:14.0]];

UIImage *newImage = [[UIImage imageNamed:@"greenButton.png"] stretchableImageWithLeftCapWidth:12.0f topCapHeight:0.0f];
[downloadButton setBackgroundImage:newImage forState:UIControlStateNormal];

[downloadButton addTarget:self action:@selector(downloadNewItem) forControlEvents:UIControlEventTouchDown];

downloadButton.backgroundColor = [UIColor clearColor];
[downloadDisplayView addSubview:downloadButton];
Brad Larson
+6  A: 

Setting the background color of the view for a rounded-rect button will not change the background color of the button. Try making the button a custom button (the first drop-down in the inspector) and then setting the background color. You will get the desired effect :)

lostInTransit
But how do you keep the button rounded when you do this?
Neo42
If you want to keep the button rounded, you'll have to use a custom image as the cell background with the background color set as clear.
lostInTransit
+3  A: 

Hey Alex,

Set your button type to "custom" in the button attributes palette. This will give you a square button with whatever color you picked for the background.

If you want a button that looks more like a traditional button, but has a different color your going to need to go into some kind of image editing software and create it (I use photoshop for custom buttons).

acreek
+1  A: 

keremk was right when he said to change the 'view' background color when you have clicked on the button and gone into the inspector. This changes the little corners into whatever colour you picked.

Domness
+1  A: 

There's a private API that'll give you custom-colored shiny buttons (like the ones in the Timer app) without having to make your own images. The class is UIGlassButton, and can be set up pretty much the same as an ordinary custom button (-initWithFrame: etc.); the tinting method is -setTintColor:. Keep in mind the usual caveats with private APIs - it may change in future OS builds and if Apple feels like it (and like disassembling things) they can conceivably use it as a reason to reject your app.

Noah Witherspoon
+1  A: 

I solved this problem by creating my own button in Fireworks. I drew a rounded rectangle of about the size I wanted, with the fill color and border color I wanted. Trim the canvas, and save as a PNG. In XCode, add the file to the Resources folder. You can use a Custom button in Interface Builder and specify the image as that PNG. It will resize it as needed, put the text on top, etc. The curve of the corners may distort if you have to resize it much from the original.

+14  A: 

I read your question to require (as I do) a programmatic way to set button color. It's a glaring omission from the UIKit, and I couldn't get the undocumented UIGlassButton to work.

I've solved this with a single segment UISegmentedControl, which allows you to set the tintColor:

UISegmentedControl * btn = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:name]];
btn.momentary = YES;
btn.segmentedControlStyle = UISegmentedControlStyleBar;
btn.tintColor = color;
[btn addTarget:self action:@selector(action:) forControlEvents:UIControlEventValueChanged];

Note please that the momentary and segmentedControlStyle properties do matter, and that an image can be used instead of a NSString * name.

A stretchable image with end caps works fine if you can use a finite set of canned images, but that doesn't fit the requirement! E.g.,

buttonImage   = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:26 topCapHeight:16];
Tim James
Well, maybe you didn't require a programmatic way. That was what I needed. I expect it works in Interface Builder as well!
Tim James
It's a nice solution but unfortunately you don't get the button having the touch down effect when you click/touch on it.
Chris S
+1  A: 

This link provides an elegant solution to your problem ... http://www.cimgf.com/2010/01/28/fun-with-uibuttons-and-core-animation-layers/

Mark Shephard
+2  A: 

To keep the button rounded, what about using

view.layer.cornerRadius = 8;

described here

http://stackoverflow.com/questions/510382/how-do-i-create-a-round-cornered-uilabel-on-the-iphone

Alex
This totally works for me. Just be sure to include the following line. #import <QuartzCore/QuartzCore.h> mj
mj_
+5  A: 

http://github.com/dermdaly/ButtonMaker

You can generate UIbutton image using this application...and can set it as background image of your button

Sijo
Who is U and how do they know what I'm working on? :/
Lunatik
U knows everything.
kirk.burleson
Hey that is excellent work!
OOP_Master
+1  A: 

Tim James' solution (a single-segment segmented control) worked for me when I wanted a simple 'Save' button with a decent blue gradient background. I simply created a 2 segment control in the nib, set up the first segment as I wanted it and then programatically removed the second segment under -viewWillAppear using [mySegmentedControl removeSegmentAtIndex:1 animated:NO]. For my purposes 'Momentary' needed to be active (ticked) for the Segmented Control's first segment in the nib and 'Selected' was not active for either segment. 'Value Changed' is the Segmented Control's Action to connect up.

iTinck