Skip to content
This repository has been archived by the owner on Jun 19, 2019. It is now read-only.

Setting UIButton background color

David Nedrow edited this page Oct 18, 2017 · 1 revision

The following example shows how to set the background color of a UIButton using a class category with properties.

We want to be able to set the background color by simply setting a UIColor property and a control state.

To do this, we start with the following category on UIButton, courtesy of Zachary Wilson:

UIButton+PLColor.h

#import <UIKit/UIKit.h>

@interface UIButton (PLColor)
@property (nonatomic, strong) UIColor *backgroundColor;

- (void)setBackgroundColor:(UIColor *)color forState:(UIControlState)state;

@end

UIButton+PLColor.m

#import "UIButton+PLColor.h"

@implementation UIButton (PLColor)


+ (UIImage *)imageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

- (void)setBackgroundColor:(UIColor *)color forState:(UIControlState)state
{
    UIImage *image = [UIButton imageWithColor:color];

    [self setBackgroundImage:image forState:state];
}

@end

Next we need to set up the CASObjectClassDescriptor to handle the property and matching method from the category. This goes before your call to set the defaultStyler for CASStyler, typically in main.m or AppDelegate.m. Below is the example method. Note that we have to provide a dictionary of control states, as Objective-C does not provide an introspection mechanism for them:

AppDelegate.m (application:didFinishLaunchingWithOptions:)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    CASObjectClassDescriptor *buttonClassDescriptor = [CASStyler .defaultStyler objectClassDescriptorForClass:UIButton.class];
    CASArgumentDescriptor *colorArg = [CASArgumentDescriptor argWithClass:UIColor.class];
    NSDictionary *controlStateMap = @{
            @"normal"       : @(UIControlStateNormal),
            @"highlighted"  : @(UIControlStateHighlighted),
            @"disabled"     : @(UIControlStateDisabled),
            @"selected"     : @(UIControlStateSelected),
    };
    CASArgumentDescriptor *stateArg = [CASArgumentDescriptor argWithName:@"state" valuesByName:controlStateMap];
    [buttonClassDescriptor setArgumentDescriptors:@[colorArg, stateArg] setter:@selector(setBackgroundColor:forState:) forPropertyKey:@"backgroundColor"];

#if TARGET_IPHONE_SIMULATOR
    NSString *absoluteFilePath = CASAbsoluteFilePath(@"Styles/stylesheet.cas");
    [CASStyler defaultStyler].watchFilePath = absoluteFilePath;
#endif
    return YES;
}

Now, we can define our button background colors in the stylesheet. This example styles UIButton and its descendants.

stylesheet.cas

^UIButton {
    backgroundColor[state:normal]: #00FF00
    backgroundColor[state:disabled]: #0000FF
    backgroundColor[state:highlighted]: #FF0000
    title-color[state:normal] #FF0000
    title-color[state:highlighted] #00FF00
    title-label: @{
        font: OpenSans-SemiBold 10
    }
}