Skip to content

Commit

Permalink
Better (more beautiful) TabBarItem
Browse files Browse the repository at this point in the history
  • Loading branch information
myell0w committed Apr 25, 2012
1 parent 62bfbd8 commit 1346d02
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 20 deletions.
4 changes: 4 additions & 0 deletions NGTabBarController/NGTabBarItem.h
Expand Up @@ -13,6 +13,10 @@
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, copy) NSString *title;

@property (nonatomic, strong) UIColor *selectedImageTintColor;
@property (nonatomic, strong) UIColor *titleColor;
@property (nonatomic, strong) UIColor *selectedTitleColor;

+ (NGTabBarItem *)itemWithTitle:(NSString *)title image:(UIImage *)image;

- (void)setSize:(CGSize)size;
Expand Down
128 changes: 108 additions & 20 deletions NGTabBarController/NGTabBarItem.m
@@ -1,9 +1,14 @@
#import "NGTabBarItem.h"


@interface NGTabBarItem ()
#define kNGDefaultTintColor [UIColor colorWithRed:41.0/255.0 green:147.0/255.0 blue:239.0/255.0 alpha:1.0]
#define kNGDefaultTitleColor [UIColor darkGrayColor]
#define kNGDefaultSelectedTitleColor [UIColor whiteColor]

@interface NGTabBarItem () {
BOOL _selectedByUser;
}

@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UILabel *titleLabel;

@end
Expand All @@ -12,7 +17,10 @@ @interface NGTabBarItem ()
@implementation NGTabBarItem

@synthesize selected = _selected;
@synthesize imageView = _imageView;
@synthesize selectedImageTintColor = _selectedImageTintColor;
@synthesize titleColor = _titleColor;
@synthesize selectedTitleColor = _selectedTitleColor;
@synthesize image = _image;
@synthesize titleLabel = _titleLabel;

////////////////////////////////////////////////////////////////////////
Expand All @@ -30,13 +38,13 @@ + (NGTabBarItem *)itemWithTitle:(NSString *)title image:(UIImage *)image {

- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
self.backgroundColor = [UIColor redColor];

_imageView = [[UIImageView alloc] initWithFrame:CGRectZero];
[self addSubview:_imageView];
_selectedByUser = NO;

_titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
_titleLabel.backgroundColor = [UIColor clearColor];
_titleLabel.font = [UIFont boldSystemFontOfSize:10.f];
_titleLabel.textAlignment = UITextAlignmentCenter;
_titleLabel.textColor = kNGDefaultTitleColor;
[self addSubview:_titleLabel];
}

Expand All @@ -50,8 +58,77 @@ - (id)initWithFrame:(CGRect)frame {
- (void)layoutSubviews {
[super layoutSubviews];

// TODO:
self.titleLabel.frame = self.bounds;
if (self.image != nil) {
CGRect textLabelFrame = CGRectMake(0.f, self.bounds.size.height-self.titleLabel.font.lineHeight,
self.bounds.size.width,
self.titleLabel.font.lineHeight);

self.titleLabel.frame = textLabelFrame;
} else {
self.titleLabel.frame = self.bounds;
}
}

- (void)drawRect:(CGRect)rect {
CGRect bounds = self.bounds;
CGContextRef context = UIGraphicsGetCurrentContext();

if (self.image != nil) {
CGContextSaveGState(context);

// flip the coordinates system
CGContextTranslateCTM(context, 0.0, bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

// draw an image in the center of the cell (offset to the top)
CGSize imageSize = self.image.size;
CGRect imageRect = CGRectMake(floorf(((bounds.size.width-imageSize.width)/2.0)),
floorf(((bounds.size.height-imageSize.height)/2.0)) + 5.f,
imageSize.width,
imageSize.height);

// draw either a selection gradient/glow or a regular image
if (_selectedByUser) {
// setup shadow
CGSize shadowOffset = CGSizeMake(0.0f, 1.0f);
CGFloat shadowBlur = 3.0;
CGColorRef cgShadowColor = [[UIColor blackColor] CGColor];

// setup gradient
CGFloat alpha0 = 0.8;
CGFloat alpha1 = 0.6;
CGFloat alpha2 = 0.0;
CGFloat alpha3 = 0.1;
CGFloat alpha4 = 0.5;
CGFloat locations[5] = {0,0.55,0.55,0.7,1};

CGFloat components[20] = {1,1,1,alpha0,1,1,1,alpha1,1,1,1,alpha2,1,1,1,alpha3,1,1,1,alpha4};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef colorGradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, (size_t)5);
CGColorSpaceRelease(colorSpace);

// set shadow
CGContextSetShadowWithColor(context, shadowOffset, shadowBlur, cgShadowColor);

// set transparency layer and clip to mask
CGContextBeginTransparencyLayer(context, NULL);
CGContextClipToMask(context, imageRect, [self.image CGImage]);

// fill and end the transparency layer
CGContextSetFillColorWithColor(context, [self.selectedImageTintColor CGColor]);
CGContextFillRect(context, imageRect);
CGPoint start = CGPointMake(CGRectGetMidX(imageRect), imageRect.origin.y);
CGPoint end = CGPointMake(CGRectGetMidX(imageRect)-imageRect.size.height/4, imageRect.size.height+imageRect.origin.y);
CGContextDrawLinearGradient(context, colorGradient, end, start, 0);
CGContextEndTransparencyLayer(context);

CGGradientRelease(colorGradient);
} else {
CGContextDrawImage(context, imageRect, self.image.CGImage);
}

CGContextRestoreGState(context);
}
}

////////////////////////////////////////////////////////////////////////
Expand All @@ -61,26 +138,22 @@ - (void)layoutSubviews {
- (void)setSelected:(BOOL)selected {
[super setSelected:selected];

// somehow self.selected always returns NO, so we store it in our own iVar
_selectedByUser = selected;

if (selected) {
self.backgroundColor = [UIColor greenColor];
self.titleLabel.textColor = [UIColor whiteColor];
} else {
self.backgroundColor = [UIColor redColor];
self.titleLabel.textColor = [UIColor lightGrayColor];
}

[self setNeedsDisplay];
}

////////////////////////////////////////////////////////////////////////
#pragma mark - NGTabBarItem
////////////////////////////////////////////////////////////////////////

- (void)setImage:(UIImage *)image {
self.imageView.image = image;
[self setNeedsLayout];
}

- (UIImage *)image {
return self.imageView.image;
}

- (void)setTitle:(NSString *)title {
self.titleLabel.text = title;
[self setNeedsLayout];
Expand All @@ -94,6 +167,21 @@ - (void)setSize:(CGSize)size {
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;

[self setNeedsDisplay];
[self setNeedsLayout];
}

- (UIColor *)selectedImageTintColor {
return _selectedImageTintColor ?: kNGDefaultTintColor;
}

- (UIColor *)titleColor {
return _titleColor ?: kNGDefaultTitleColor;
}

- (UIColor *)selectedTitleColor {
return _selectedTitleColor ?: kNGDefaultSelectedTitleColor;
}

@end

0 comments on commit 1346d02

Please sign in to comment.