Instantly share code, notes, and snippets.
Created
February 2, 2012 14:37
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save leapingbytes/1723748 to your computer and use it in GitHub Desktop.
LBGradientButton
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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