From 1346d02bf5d995c710a8e0064a6a5bd297e55259 Mon Sep 17 00:00:00 2001 From: Matthias Tretter Date: Wed, 25 Apr 2012 14:48:00 +0200 Subject: [PATCH] Better (more beautiful) TabBarItem --- NGTabBarController/NGTabBarItem.h | 4 + NGTabBarController/NGTabBarItem.m | 128 +++++++++++++++++++++++++----- 2 files changed, 112 insertions(+), 20 deletions(-) diff --git a/NGTabBarController/NGTabBarItem.h b/NGTabBarController/NGTabBarItem.h index 2c7bd34..3a6a4ce 100644 --- a/NGTabBarController/NGTabBarItem.h +++ b/NGTabBarController/NGTabBarItem.h @@ -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; diff --git a/NGTabBarController/NGTabBarItem.m b/NGTabBarController/NGTabBarItem.m index bd43586..051c7f7 100644 --- a/NGTabBarController/NGTabBarItem.m +++ b/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 @@ -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; //////////////////////////////////////////////////////////////////////// @@ -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]; } @@ -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); + } } //////////////////////////////////////////////////////////////////////// @@ -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]; @@ -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