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
Building further on @Denny1989 I've solved a problem getting errors (invalid context 0x0) when setting up the button in viewDidLoad. The button needs to be laid out before it has a size and thus cannot be depended on until after the view appears. This category adds a color for UIControlStateNormal. If other control states are necessary for your app you need to add them similarly to the category.
// UIButton+ColoredBackground.h
#import
@interface UIButton (ColoredBackground)
@property (nonatomic, retain) UIColor *buttonColorNormal;
@property (nonatomic, retain) NSNumber *madeBackgroundImages;
- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state;
- (void)drawRect:(CGRect)rect;
- (void)awakeFromNib;
@end
and
// UIButton+ColoredBackground.m
#import "UIButton+ColoredBackground.h"
#import
#import
#define kCornerRadius 8.0f
#define kStrokeColor [UIColor darkGrayColor]
#define kStrokeWidth 1.0f
@implementation UIButton (ColoredBackground)
static char UIB_ButtonColorNormal_KEY;
static char UIB_MadeBackgroundImages_KEY;
@dynamic buttonColorNormal;
-(void)setButtonColorNormal:(NSObject *)buttonColorNormal
{
objc_setAssociatedObject(self, &UIB_ButtonColorNormal_KEY, buttonColorNormal, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSObject*)buttonColorNormal
{
return (NSObject*)objc_getAssociatedObject(self, &UIB_ButtonColorNormal_KEY);
}
@dynamic madeBackgroundImages;
-(void)setMadeBackgroundImages:(NSObject *)madeBackgroundImages
{
objc_setAssociatedObject(self, &UIB_MadeBackgroundImages_KEY, madeBackgroundImages, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSObject*)madeBackgroundImages
{
return (NSObject*)objc_getAssociatedObject(self, &UIB_MadeBackgroundImages_KEY);
}
- (void)awakeFromNib {
[self setMadeBackgroundImages:[NSNumber numberWithBool:FALSE]];
[super awakeFromNib];
}
- (void)drawRect:(CGRect)rect {
// if background images were not created from color do so here
// if self.buttonColorNormal is not set behaves like normal button
if ((self.buttonColorNormal)&&(![[self madeBackgroundImages] boolValue])) {
[self setBackgroundColor:[self buttonColorNormal] forState:UIControlStateNormal];
[self setMadeBackgroundImages:[NSNumber numberWithBool:TRUE]];
}
[super drawRect:rect];
}
- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state {
gcSize = CGSizeMake(2*kCornerRadius +1, self.bounds.size.height);
UIGraphicsBeginImageContext(gcSize);
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
UIColor *gradientStart = [UIColor colorWithRed:0.80 green:0.80 blue:0.80 alpha:0.2];
UIColor * gradientEnd = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.5];
NSArray *colors = [NSArray arrayWithObjects:(id)gradientStart.CGColor, (id)gradientEnd.CGColor, nil];
CGFloat locations[2] = { 0.0f, 1.0f };
CGGradientRef _gradient = CGGradientCreateWithColors(rgb, (__bridge CFArrayRef)colors, locations);
CGColorSpaceRelease(rgb);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeOverlay);
CGContextDrawLinearGradient(UIGraphicsGetCurrentContext(), _gradient, CGPointMake(0.0, kStrokeWidth), CGPointMake(0.0, self.bounds.size.height-kStrokeWidth), 0);
UIBezierPath *outsideEdge = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0.0, 0.0, gcSize.width, gcSize.height) cornerRadius:kCornerRadius];
[backgroundColor setFill];
[kStrokeColor setStroke];
outsideEdge.lineWidth = kStrokeWidth;
[outsideEdge stroke];
[outsideEdge fill];
CFRelease(_gradient);
// Create the background image
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Set image as button's background image (stretchable) for the given state
[self setBackgroundImage:[image stretchableImageWithLeftCapWidth:kCornerRadius topCapHeight:0.0] forState:state];
// Ensure rounded button
self.clipsToBounds = YES;
self.layer.cornerRadius = kCornerRadius;
// add colored border
self.layer.borderColor = kStrokeColor.CGColor;
self.layer.borderWidth = kStrokeWidth;
}
@end
usage
- (void)viewDidLoad
{
[myButton setButtonColorNormal:[UIColor redColor]];
}
Be sure to make the button type custom or drawRect may not be called.