參考:http://www.jianshu.com/p/46f61bc7a938,https://github.com/Mringkang/KBCustomCenterTabbar
效果:
PS:這里需要用到UIView一個分類的一些屬性,參考http://www.cnblogs.com/guitarandcode/p/5758995.html ,圖標素材等自行上網找或者自己設計,這里就不提供了。最后在StoryBoard中選擇TabBarController對應下面自定義的TabBarController即可
自定義TabBar:
MyTabBar.h
1 #import <UIKit/UIKit.h> 2 3 @class MyTabBar; 4 5 //MyTabBar的代理必須實現addButtonClick,以響應中間“+”按鈕的點擊事件 6 @protocol MyTabBarDelegate <NSObject> 7 8 -(void)addButtonClick:(MyTabBar *)tabBar; 9 10 @end 11 12 @interface MyTabBar : UITabBar 13 14 //指向MyTabBar的代理 15 @property (nonatomic,weak) id<MyTabBarDelegate> myTabBarDelegate; 16 17 @end
MyTabBar.m
1 #import "MyTabBar.h" 2 #import "UIView+Category.h" 3 4 #define AddButtonMargin 10 5 6 @interface MyTabBar() 7 8 //指向中間“+”按鈕 9 @property (nonatomic,weak) UIButton *addButton; 10 //指向“添加”標簽 11 @property (nonatomic,weak) UILabel *addLabel; 12 13 @end 14 15 @implementation MyTabBar 16 17 /* 18 // Only override drawRect: if you perform custom drawing. 19 // An empty implementation adversely affects performance during animation. 20 - (void)drawRect:(CGRect)rect { 21 // Drawing code 22 } 23 */ 24 25 -(instancetype)initWithFrame:(CGRect)frame 26 { 27 if(self = [super initWithFrame:frame]) 28 { 29 //創建中間“+”按鈕 30 UIButton *addBtn = [[UIButton alloc] init]; 31 //設置默認背景圖片 32 [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon"] forState:UIControlStateNormal]; 33 //設置按下時背景圖片 34 [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon-Active"] forState:UIControlStateHighlighted]; 35 //添加響應事件 36 [addBtn addTarget:self action:@selector(addBtnDidClick) forControlEvents:UIControlEventTouchUpInside]; 37 //將按鈕添加到TabBar 38 [self addSubview:addBtn]; 39 40 self.addButton = addBtn; 41 } 42 return self; 43 } 44 45 //響應中間“+”按鈕點擊事件 46 -(void)addBtnDidClick 47 { 48 if([self.myTabBarDelegate respondsToSelector:@selector(addButtonClick:)]) 49 { 50 [self.myTabBarDelegate addButtonClick:self]; 51 } 52 } 53 54 -(void)layoutSubviews 55 { 56 [super layoutSubviews]; 57 58 //去掉TabBar上部的橫線 59 for (UIView *view in self.subviews) 60 { 61 if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height <= 1) //橫線的高度為0.5 62 { 63 UIImageView *line = (UIImageView *)view; 64 line.hidden = YES; 65 } 66 } 67 68 //設置“+”按鈕的位置 69 self.addButton.centerX = self.centerX; 70 self.addButton.centerY = self.height * 0.5 - 1.5 * AddButtonMargin; 71 //設置“+”按鈕的大小為圖片的大小 72 self.addButton.size = CGSizeMake(self.addButton.currentBackgroundImage.size.width, self.addButton.currentBackgroundImage.size.height); 73 74 //創建並設置“+”按鈕下方的文本為“添加” 75 UILabel *addLbl = [[UILabel alloc] init]; 76 addLbl.text = @"添加"; 77 addLbl.font = [UIFont systemFontOfSize:10]; 78 addLbl.textColor = [UIColor grayColor]; 79 [addLbl sizeToFit]; 80 81 //設置“添加”label的位置 82 addLbl.centerX = self.addButton.centerX; 83 addLbl.centerY = CGRectGetMaxY(self.addButton.frame) + 0.5 * AddButtonMargin + 0.5; 84 85 [self addSubview:addLbl]; 86 87 self.addLabel = addLbl; 88 89 int btnIndex = 0; 90 //系統自帶的按鈕類型是UITabBarButton,找出這些類型的按鈕,然后重新排布位置,空出中間的位置 91 Class class = NSClassFromString(@"UITabBarButton"); 92 for (UIView *btn in self.subviews) {//遍歷TabBar的子控件 93 if ([btn isKindOfClass:class]) {//如果是系統的UITabBarButton,那么就調整子控件位置,空出中間位置 94 //每一個按鈕的寬度等於TabBar的三分之一 95 btn.width = self.width / 3; 96 97 btn.x = btn.width * btnIndex; 98 99 btnIndex++; 100 //如果索引是1(即“+”按鈕),直接讓索引加一 101 if (btnIndex == 1) { 102 btnIndex++; 103 } 104 105 } 106 } 107 //將“+”按鈕放到視圖層次最前面 108 [self bringSubviewToFront:self.addButton]; 109 } 110 111 //重寫hitTest方法,去監聽"+"按鈕和“添加”標簽的點擊,目的是為了讓凸出的部分點擊也有反應 112 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { 113 114 //這一個判斷是關鍵,不判斷的話push到其他頁面,點擊“+”按鈕的位置也是會有反應的,這樣就不好了 115 //self.isHidden == NO 說明當前頁面是有TabBar的,那么肯定是在根控制器頁面 116 //在根控制器頁面,那么我們就需要判斷手指點擊的位置是否在“+”按鈕或“添加”標簽上 117 //是的話讓“+”按鈕自己處理點擊事件,不是的話讓系統去處理點擊事件就可以了 118 if (self.isHidden == NO) 119 { 120 121 //將當前TabBar的觸摸點轉換坐標系,轉換到“+”按鈕的身上,生成一個新的點 122 CGPoint newA = [self convertPoint:point toView:self.addButton]; 123 //將當前TabBar的觸摸點轉換坐標系,轉換到“添加”標簽的身上,生成一個新的點 124 CGPoint newL = [self convertPoint:point toView:self.addLabel]; 125 126 //判斷如果這個新的點是在“+”按鈕身上,那么處理點擊事件最合適的view就是“+”按鈕 127 if ( [self.addButton pointInside:newA withEvent:event]) 128 { 129 return self.addButton; 130 } 131 //判斷如果這個新的點是在“添加”標簽身上,那么也讓“+”按鈕處理事件 132 else if([self.addLabel pointInside:newL withEvent:event]) 133 { 134 return self.addButton; 135 } 136 else 137 {//如果點不在“+”按鈕身上,直接讓系統處理就可以了 138 139 return [super hitTest:point withEvent:event]; 140 } 141 } 142 else 143 { 144 //TabBar隱藏了,那么說明已經push到其他的頁面了,這個時候還是讓系統去判斷最合適的view處理就好了 145 return [super hitTest:point withEvent:event]; 146 } 147 } 148 149 @end
自定義TabBarController:
MyTabBarController.h
1 #import <UIKit/UIKit.h> 2 3 @interface MyTabBarController : UITabBarController 4 5 @end
MyTabBarController.m
1 #import "MyTabBarController.h" 2 #import "MyTabBar.h" 3 4 5 @interface MyTabBarController () <MyTabBarDelegate> //實現自定義TabBar協議 6 7 @end 8 9 @implementation MyTabBarController 10 11 - (void)viewDidLoad { 12 [super viewDidLoad]; 13 // Do any additional setup after loading the view. 14 15 //設置TabBar上第一個Item(明細)選中時的圖片 16 UIImage *listActive = [UIImage imageNamed:@"ListIcon - Active(blue)"]; 17 UITabBarItem *listItem = self.tabBar.items[0]; 18 //始終按照原圖片渲染 19 listItem.selectedImage = [listActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 20 21 22 //設置TabBar上第二個Item(報表)選中時的圖片 23 UIImage *chartActive = [UIImage imageNamed:@"ChartIcon - Active(blue)"]; 24 UITabBarItem *chartItem = self.tabBar.items[1]; 25 //始終按照原圖片渲染 26 chartItem.selectedImage = [chartActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 27 28 //創建自定義TabBar 29 MyTabBar *myTabBar = [[MyTabBar alloc] init]; 30 myTabBar.myTabBarDelegate = self; 31 32 //利用KVC替換默認的TabBar 33 [self setValue:myTabBar forKey:@"tabBar"]; 34 } 35 36 37 -(void)viewDidLayoutSubviews 38 { 39 [super viewDidLayoutSubviews]; 40 //設置TabBar的TintColor 41 self.tabBar.tintColor = [UIColor colorWithRed:89/255.0 green:217/255.0 blue:247/255.0 alpha:1.0]; 42 } 43 44 - (void)didReceiveMemoryWarning { 45 [super didReceiveMemoryWarning]; 46 // Dispose of any resources that can be recreated. 47 } 48 49 50 51 #pragma mark - MyTabBarDelegate 52 -(void)addButtonClick:(MyTabBar *)tabBar 53 { 54 //測試中間“+”按鈕是否可以點擊並處理事件 55 UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"test" message:@"Test" preferredStyle:UIAlertControllerStyleAlert]; 56 UIAlertAction *action = [UIAlertAction actionWithTitle:@"test" style:UIAlertActionStyleDefault handler:nil]; 57 [controller addAction:action]; 58 [self presentViewController:controller animated:YES completion:nil]; 59 60 } 61 62 @end