software-mariodiana
10/3/2013 - 1:33 AM

How to create a bordered button in iOS 7 (similar to Apple's round rectangular buttons in iOS 7 apps).

How to create a bordered button in iOS 7 (similar to Apple's round rectangular buttons in iOS 7 apps).

/*
 * MyCustomRoundRectButton.h
 */

#import <UIKit/UIKit.h>

@interface MyCustomRoundRectButton : UIButton

@end


/*
 * MyCustomRoundRectButton.m
 */

#import "MyCustomRoundRectButton.h"

@interface MyCustomRoundRectButton ()

@property (strong, nonatomic) UIColor *borderColor;
@property (strong, nonatomic) UIColor *primaryColor;
@property (strong, nonatomic) UIColor *secondaryColor;

@end


@implementation MyCustomRoundRectButton

- (void)dealloc
{
    self.borderColor = nil;
    self.primaryColor = nil;
    self.secondaryColor = nil;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    
    if (self) {
        
        // Default RGB color for System type UIButton (light blue)
        UIColor *defaultPrimaryColor = [UIColor colorWithRed:0.0f
                                                       green:0.478431f
                                                        blue:1.0f
                                                       alpha:1.0f];
        
        _borderColor = defaultPrimaryColor;
        [self setTitleColor:defaultPrimaryColor forState:UIControlStateNormal];
        [self setBackgroundColor:nil];
    }
    
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    
    if (self) {
        // Grab color from Nib
        _borderColor = [self titleColorForState:UIControlStateNormal];
    }
    
    return self;
}

- (void)drawRect:(CGRect)rect
{
    [[self layer] setMasksToBounds:YES];
    [[self layer] setBorderColor:[[self borderColor] CGColor]];
    
    // These settings seem close to what Apple does in iOS 7 with button borders
    [[self layer] setCornerRadius:5.0f];
    [[self layer] setBorderWidth:1.0f];
}

- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state
{
    if (state == UIControlStateNormal) {
        // Allow client to change, while keeping border color in sync with title color.
        [self setBorderColor:color];
    }
    
    [super setTitleColor:color forState:state];
}

- (UIColor *)ancestorViewBackgroundColor
{
    UIColor *color = nil;
    
    UIView *parent = [self superview];
    
    // Continue up the superview chain until we find a color
    while (parent) {
        if ([parent backgroundColor]) {
            color = [parent backgroundColor];
            break;
        }
        parent = [parent superview];
    }
    
    return color;
}

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    [self setPrimaryColor:[self titleColorForState:UIControlStateNormal]];
    [self setSecondaryColor:[self backgroundColor]];
    
    [self setBackgroundColor:[self primaryColor]];
    
    if (![self secondaryColor]) {
        [self setTitleColor:[self ancestorViewBackgroundColor]
                   forState:UIControlStateHighlighted];
    }
    else {
        [self setTitleColor:[self secondaryColor] forState:UIControlStateHighlighted];
    }
    
    return YES;
}

- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
    [self setTitleColor:[self primaryColor] forState:UIControlStateNormal];
    [self setBackgroundColor:[self secondaryColor]];
}

@end