【iOS】UIButtonでハイライトや無効時の色を指定する

UIButtonを拡張して、UIControlStateHighlightedやUIControlStateDisabledにsetBackgroundColorで色を指定する方法です。

UIButtonの拡張クラス

StateColorButton.h

@interface StateColorButton : UIButton

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

@end
#import "StateColorButton.h"

@interface StateColorButton()

@property (nonatomic, strong) NSMutableDictionary *backgroundColors;

@end

@implementation StateColorButton
#pragma mark - Background Colors

- (void)setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state {
    if (!self.backgroundColors) {
        self.backgroundColors = [[NSMutableDictionary alloc] init];
        
    }
    if (backgroundColor) {
        self.backgroundColors[@(state)] = backgroundColor;
    }
    
    if (state == UIControlStateNormal) {
        self.backgroundColor = backgroundColor;
    }
}

- (void)transitionBackgroundToColor:(UIColor*)color {
    CATransition *animation = [CATransition animation];
    animation.type = kCATransitionFade;
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
    [self.layer addAnimation:animation forKey:@"EaseOut"];
    self.backgroundColor = color;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    
    UIColor *selectedColor = self.backgroundColors[@(UIControlStateHighlighted)];
    if (selectedColor) {
        [self transitionBackgroundToColor:selectedColor];
    }
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    
    UIColor *normalColor = self.backgroundColors[@(UIControlStateNormal)];
    if (normalColor) {
        [self transitionBackgroundToColor:normalColor];
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    
    UIColor *normalColor = self.backgroundColors[@(UIControlStateNormal)];
    if (normalColor) {
        [self transitionBackgroundToColor:normalColor];
    }
}

- (void)setEnabled:(BOOL)enabled
{
    [super setEnabled:enabled];
    if (enabled){
        self.backgroundColor = self.backgroundColors[@(UIControlStateNormal)];
    }else{
        self.backgroundColor = self.backgroundColors[@(UIControlStateDisabled)];
    }
}

@end

使い方

StateColorButton *button = [[StateColorButton alloc] initWithFrame:CGRectMake(50, 100, 200, 36)];
[button setTitle:@"button" forState:UIControlStateNormal];

// 状態に応じて色変更
[button setBackgroundColor:[UIColor blueColor] forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor greenColor] forState:UIControlStateHighlighted];
[button setBackgroundColor:[UIColor blackColor] forState:UIControlStateDisabled];

[self.view addSubview:button];

GitHub

https://github.com/maximinstantcoffee/statecolorbutton