Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C highlight UIButton when selected / unselected

I have a UIButton inside a UIView, when the UIButton is selected I would like have a background colour of dark gray...is this possible?

UIView *toolbar = [[UIView alloc]initWithFrame:CGRectMake(10, 50, 40, 160)];
    [toolbar setBackgroundColor:[UIColor colorWithWhite: 0.70 alpha:0.5]];

    toolbar.layer.cornerRadius = 5;

    UIButton *penTool = [UIButton buttonWithType:UIButtonTypeCustom];
    penTool.frame = CGRectMake(5, 0, 30, 30);
    [penTool setImage:[UIImage imageNamed:@"pen-but" inBundle:currentBundle compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
    [penTool addTarget:self action:@selector(drawButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
    penTool.autoresizingMask = UIViewAutoresizingNone;
    penTool.exclusiveTouch = YES;
    penTool.tag = 1;

    [toolbar addSubview:penTool];
like image 624
user979331 Avatar asked Dec 14 '22 05:12

user979331


2 Answers

What if you can do this?

[button setBackgroundColor:[UIColor greenColor] 
                  forState:UIControlStateSelected];

Let's give a great API for every state, not just selected, just like UIButton default API's ability to change image and title for every state.

BGButton.h

#import <UIKit/UIKit.h>

@interface BGButton : UIButton

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

@end

BGButton.m

#import "BGButton.h"

@implementation BGButton {
    NSMutableDictionary *_stateBackgroundColor;
}

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        _stateBackgroundColor = [[NSMutableDictionary alloc] init];
    }
    return self;
}


- (void)setBackgroundColor:(UIColor *)backgroundColor {
    [super setBackgroundColor:backgroundColor];

   /*
    * If user set button.backgroundColor we will set it to 
    * normal state's backgroundColor.
    * Check if state is on normal state to prevent background being 
    * changed for incorrect state when updateBackgroundColor method is called.
    */
    if (self.state == UIControlStateNormal) {
        [self setBackgroundColor:backgroundColor forState:UIControlStateNormal];
    }
}

- (void)setBackgroundColor:(UIColor *)backgroundColor 
                  forState:(UIControlState)state {
    NSNumber *key = [NSNumber numberWithInt:state];
    [_stateBackgroundColor setObject:backgroundColor forKey:key];
}

/*
 * state is synthesized from other flags. So we can't use KVO 
 * to listen for state changes.
 */
- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    [self stateDidChange];
}

- (void)setEnabled:(BOOL)enabled {
    [super setEnabled:enabled];
    [self stateDidChange];
}

- (void)setHighlighted:(BOOL)highlighted {
    [super setHighlighted:highlighted];
    [self stateDidChange];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    [self stateDidChange];
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesMoved:touches withEvent:event];
    [self stateDidChange];
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesEnded:touches withEvent:event];
    [self stateDidChange];
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [super touchesCancelled:touches withEvent:event];
    [self stateDidChange];
}

- (void)stateDidChange {
    [self updateBackgroundColor];
}

- (void)updateBackgroundColor {
    NSNumber *key = [NSNumber numberWithInt:self.state];
    self.backgroundColor = [_stateBackgroundColor objectForKey:key];
}

@end


You can use it like the default UIButton API

BGButton *button = [[BGButton alloc] init];

[button setBackgroundColor:[UIColor greenColor] 
                  forState:UIControlStateSelected];

[button setBackgroundColor:[UIColor blueColor] 
                  forState:UIControlStateHighlighted];

[button setBackgroundColor:[UIColor orangeColor] 
                  forState:UIControlStateDisabled];

Even if you use

button.backgroundColor = [UIColor redColor];

You will stay safe, it will be translated into

[button setBackgroundColor:[UIColor redColor] 
                  forState:UIControlStateNormal];
like image 163
Edward Anthony Avatar answered Dec 28 '22 11:12

Edward Anthony


if you have this code

[self.view addSubview:toolbar];

then just implement your button selector

-(void)drawButtonTapped:(UIButton*)button{

if (button.selected) {
    button.backgroundColor = [UIColor clearColor];
    button.selected = NO;
}else{
    button.backgroundColor = [UIColor darkGrayColor];
    button.selected = YES;
}
}
like image 43
Jamil Avatar answered Dec 28 '22 11:12

Jamil