Skip to content

Instantly share code, notes, and snippets.

@leapingbytes
Created February 2, 2012 14:37
Show Gist options
  • Save leapingbytes/1723748 to your computer and use it in GitHub Desktop.
Save leapingbytes/1723748 to your computer and use it in GitHub Desktop.
LBGradientButton
//
// TBRButton.h
// TBR
//
// Created by andrei tchijov on 2/7/11.
// Copyright 2011 Leaping Bytes, LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface LBGradientButton : UIButton {
UIButtonType tbrButtonType;
NSMutableDictionary* tintForState;
@private
}
@property(nonatomic, assign) UIButtonType tbrButtonType;
@property(nonatomic, retain) NSMutableDictionary* tintForState;
@property(nonatomic, assign, setter = setInvertIcon: ) BOOL invertIcon;
+(LBGradientButton*) buttonWithType: (UIButtonType) type;
+ (void) enumerateAllGradientButtonsInside: (UIView*) aView usingBlock: (void (^)( LBGradientButton* aButton )) aBlock;
-(void) setTint: (UIColor*) tintColor forState: (UIControlState) state;
@end
//
// TBRButton.m
// TBR
//
// Created by andrei tchijov on 2/7/11.
// Copyright 2011 Leaping Bytes, LLC. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import "LBGradientButton.h"
#import "UIImage+LBToolbox.h"
float scaleColorComponent( float value, float factor );
float scaleColorComponent( float value, float factor ) {
return value + ( 1 - value ) * factor;
}
@implementation LBGradientButton
@synthesize tbrButtonType, tintForState;
@synthesize invertIcon=_invertIcon;
static float r = 8.0;
+(LBGradientButton*) buttonWithType: (UIButtonType) type {
LBGradientButton* result = [[ LBGradientButton alloc ] initWithFrame: CGRectMake( 0.0, 0.0, 10.0, 10.0 )];
result.tbrButtonType = type;
return result;
}
+ (void) enumerateAllGradientButtonsInside: (UIView*) aView usingBlock: (void (^)( LBGradientButton* aButton )) aBlock {
for ( UIView* aSubView in aView.subviews ) {
if([ aSubView isKindOfClass: [ LBGradientButton class ]] ) {
aBlock( (LBGradientButton*)aSubView );
} else {
[ LBGradientButton enumerateAllGradientButtonsInside: aSubView usingBlock: aBlock ];
}
}
}
-(void) setTint: (UIColor*) tintColor forState: (UIControlState) state {
if( self.tintForState == nil ) {
self.tintForState = [ NSMutableDictionary dictionary ];
}
[ self.tintForState setObject: tintColor forKey: [ NSNumber numberWithInt: state ]];
}
- (void) setup {
[ self.layer setMasksToBounds: YES ];
[ self.layer setCornerRadius: r ];
}
- (void) setInvertIcon:(BOOL)invertIcon {
_invertIcon = invertIcon;
if( invertIcon ) {
UIImage* image = [ self.imageView.image invertImage ];
[ self setImage: image forState: UIControlStateNormal ];
[ self setImage: image forState: UIControlStateSelected ];
[ self setNeedsDisplay ];
}
}
- (id) initWithCoder:(NSCoder *)aDecoder {
self = [ super initWithCoder: aDecoder ];
[ self setup ];
return self;
}
- (id) initWithFrame:(CGRect)frame {
self = [ super initWithFrame: frame ];
[ self setup ];
return self;
}
#define DEGREES_TO_RADIANS(degrees) (( M_PI * degrees)/ 180)
- (UIColor*) tintColor {
UIColor* result = [ self.tintForState objectForKey: [ NSNumber numberWithInt: self.state ]];
if( result == nil ) {
[ self.tintForState objectForKey: [ NSNumber numberWithInt: UIControlStateNormal ]];
}
result = result == nil ? [ UIColor colorWithRed: 1.0 green: 1.0 blue: 1.0 alpha: 1.0 ] : result;
return result;
}
- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
UIBezierPath* path = [ UIBezierPath bezierPath ];
CGRect f = self.frame;
int d = 0;
f = CGRectInset( f, d, d );
float w = f.size.width;
float h = f.size.height;
[ path moveToPoint: CGPointMake( d + r, d ) ];
[ path addLineToPoint: CGPointMake( w - r - d, d )];
[ path addArcWithCenter: CGPointMake( w - r - d , r + d ) radius: r startAngle: DEGREES_TO_RADIANS( 270 ) endAngle: 0.0 clockwise: YES ];
[ path addLineToPoint: CGPointMake( w - d, h - r - d )];
[ path addArcWithCenter: CGPointMake( w - r - d , h - r - d ) radius: r startAngle: 0.0 endAngle: DEGREES_TO_RADIANS( 90 ) clockwise: YES ];
[ path addLineToPoint: CGPointMake( r + d, h - d )];
[ path addArcWithCenter: CGPointMake( r + d , h - r - d ) radius: r startAngle: DEGREES_TO_RADIANS( 90 ) endAngle: DEGREES_TO_RADIANS( 180 ) clockwise: YES ];
[ path addLineToPoint: CGPointMake( d, r + d )];
[ path addArcWithCenter: CGPointMake( r + d , r + d ) radius: r startAngle: DEGREES_TO_RADIANS( 180 ) endAngle: DEGREES_TO_RADIANS( 270 ) clockwise: YES ];
CGContextSaveGState( ctx );
CGColorSpaceRef bgColorspace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[3] = {0.0, 0.5, 0.5 };
UIColor* tintColor = [ self tintColor ];
const CGFloat* tintComponents = CGColorGetComponents( tintColor.CGColor );
float b1 = 0.5;
float b2 = 0.3;
UIColor* bgColor1 = [ UIColor
colorWithRed: scaleColorComponent( tintComponents[0], b1 )
green: scaleColorComponent( tintComponents[1], b1 )
blue: scaleColorComponent( tintComponents[2], b1 )
alpha: 1.0
];
UIColor* bgColor2 = [ UIColor
colorWithRed: scaleColorComponent( tintComponents[0], b2 )
green: scaleColorComponent( tintComponents[1], b2 )
blue: scaleColorComponent( tintComponents[2], b2 )
alpha: 1.0
];
CGGradientRef bgGradient = CGGradientCreateWithColors(
bgColorspace,
(__bridge CFArrayRef)[ NSArray arrayWithObjects: (id)bgColor1.CGColor, (id)bgColor2.CGColor, tintColor.CGColor, nil ],
locations
);
CGColorSpaceRelease( bgColorspace );
CGContextDrawLinearGradient( ctx, bgGradient, CGPointMake( 0.0, 0.0 ), CGPointMake( 0.0, f.size.height ), kCGGradientDrawsBeforeStartLocation| kCGGradientDrawsAfterEndLocation );
CGGradientRelease( bgGradient );
CGContextRestoreGState( ctx );
CGContextSetLineWidth( ctx, 2.0 );
CGContextSetStrokeColorWithColor( ctx, [ UIColor colorWithWhite: ( _invertIcon ? 0.8 : 0.624 ) alpha: 1.0 ].CGColor );
CGContextAddPath( ctx, path.CGPath );
CGContextStrokePath( ctx );
}
- (void) drawRect:(CGRect)rect {
// [ super drawRect: rect ];
}
@end
//
// To tint one button
//
LBGradientButton* aButton;
UIColor* tintColor = [ UIColor blueColor ];
[ aButton setTint: tintColor forState: UIControlStateNormal ];
//
// To tint all buttons under some view
//
[ LBGradientButton enumerateAllGradientButtonsInside: self.view usingBlock:^(LBGradientButton* aButton) {
[ aButton setTint: tintColor forState: UIControlStateNormal ];
[ aButton setTint: tintColor forState: UIControlStateSelected ];
[ aButton setTint: tintColor forState: UIControlStateHighlighted ];
}];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment