在开始之前我们先分析一下UITabBarController的UITabBar的基本层次。UITabBar继承自UIView,负责UITabBarController.viewControllers中每个 UIViewController.UITabBarItem的管理和显示。而UITabBarItem<-UIBarItem<-NSObject,组装了UITabBar显示的每个对象的title,imang,selectedImage以及badgeValue等数据。UITabBar的代理UITabBarDelegate在tabbar显示流程中和点击了UITabBarItem对象的时候回调给委托者。
在理解清楚了内部机制的时候我们可以整理我们自己的思路了。首先需要一个类似UITabBarItem的对象进行数据的组装,再者需要一个UIView绘制组装的数据。
为了便于区分:我们暂定义WHToolItem<-NSObject,WHToolView<-UIView两个类。
@interface WHToolItem : NSObject
@property (nonatomic, retain) UIImage *image;
@property (nonatomic, retain) UIImage *selectedImage;
@property (nonatomic, retain) NSString *title;
- (instancetype)initWithImage:(NSString *)image selectedImage:(NSString *)selectedImage title:(NSString *)title;
@end
@implementation WHToolItem
- (void)dealloc{
self.image = nil;
self.selectedImage = nil;
self.title = nil;
[super dealloc];
}
- (instancetype)initWithImage:(NSString *)image selectedImage:(NSString *)selectedImage title:(NSString *)title{
if(self = [super init]){
self.image = [UIImage imageNamed:image];
self.selectedImage = [UIImage imageNamed:selectedImage];
self.title = title;
}
return self;
}
@end
ypedef void(^WHToolViewActionHandler)(WHToolView *toolView, NSInteger indexPath, BOOL animated);
@interface WHToolView : UIView
@property (nonatomic, copy) WHToolViewActionHandler actionHandler;
- (instancetype)initWithToolItem:(NSMutableArray *)arrToolItem indexPath:(NSInteger)indexPath;
- (void)reloadBadge:(NSString *)badge atIndexPath:(NSInteger)indexPath;
@end
@implementation WHToolView
- (void)dealloc{
self.arrToolItem = nil;
self.actionHandler = nil;
self.dicToolView = nil;
[super dealloc];
}
- (id)initWithToolItem:(NSMutableArray *)arrToolItem indexPath:(NSInteger)indexPath{
if(self = [super initWithFrame:frame]){
self.arrToolItem = arrToolItem;
self.indexPath = indexPath;
self.tapGesture = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureAction:)] autorelease];
[self addGestureRecognizer:_tapGesture];
}
return self;
}
- (void)tapGestureAction:(UITapGestureRecognizer *)tapGesture{
CGPoint point = [tapGesture locationInView:self];
if(CGRectContainsPoint(self.bounds, point)){
NSInteger indexPath = point.x*_arrToolItem.count/CGRectGetWidth(self.bounds);
if(indexPath != _indexPath){
self.indexPath = indexPath;
[self reloadBadge:@"" atIndexPath:_indexPath];
[self setNeedsDisplay];
if(_actionHandler){
self.actionHandler(self, _indexPath, NO);
}
}
}
}
- (void)reloadBadge:(NSString *)badge atIndexPath:(NSInteger)indexPath{
if((_arrToolItem != nil) && (_arrToolItem.count > 0) && (indexPath >= 0) && (indexPath < _arrToolItem.count)){
self.dicToolView = [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"toolView"]];
if(badge.length > 0){
[_dicToolView setObject:badge forKey:[NSString stringWithFormat:@"indexPath%@",@(indexPath)]];
}
else{
[_dicToolView removeObjectForKey:[NSString stringWithFormat:@"indexPath%@",@(indexPath)]];
}
[[NSUserDefaults standardUserDefaults] setObject:_dicToolView forKey:@"toolView"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self setNeedsDisplay];
}
}
- (void)drawRect:(CGRect)rect{
CGContextRef content = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(content, 0.5);
CGContextSetStrokeColorWithColor(content, [UIColor lightGrayColor].CGColor);
CGContextMoveToPoint(content, 0, 0+0.5/2);
CGContextAddLineToPoint(content, CGRectGetWidth(self.bounds), 0+0.5/2);
CGContextDrawPath(content, kCGPathStroke);
if(_arrToolItem != nil && _arrToolItem.count > 0){
CGFloat widthItem = CGRectGetWidth(self.bounds)/_arrToolItem.count;
CGFloat topItem = 4;
NSDictionary *dicToolView = [[NSUserDefaults standardUserDefaults] objectForKey:@"toolView"];
for(NSInteger loop = 0; loop < _arrToolItem.count; loop++){
WHToolItem *toolItem = [_arrToolItem objectAtIndex:loop];
UIImage *image = nil;
NSString *title = toolItem.title;
if(_indexPath == loop){
image = toolItem.selectedImage;
[KMainViewColor set];
}
else{
image = toolItem.image;
[KTitleColorBlack set];
}
if(image){
[image drawInRect:CGRectMake(widthItem*loop+(widthItem-26)/2,topItem,26,26) blendMode:kCGBlendModeNormal alpha:0.70];
}
if(title.length > 0){
[title drawInCenter:CGRectMake(0+widthItem*loop, 28, widthItem, 22) withFont:[UIFont systemFontOfSize:11] alignment:NSTextAlignmentCenter];
}
NSString *aKey = [NSString stringWithFormat:@"indexPath%@",@(loop).stringValue];
NSString *badge = [dicToolView objectForKey: aKey];
if(badge.length){
CGContextSetFillColorWithColor(content, [UIColor redColor].CGColor);
CGContextAddPath(content, [UIBezierPath bezierPathWithRoundedRect:CGRectMake(widthItem*(loop+0.5)+12, topItem, 8, 8) cornerRadius:4].CGPath);
CGContextDrawPath(content, kCGPathFill);
}
}
}
}
@end