1. 程式人生 > >iOS開發-實現TabBar中間凸起按鈕、不規則按鈕(自定義TabBar)

iOS開發-實現TabBar中間凸起按鈕、不規則按鈕(自定義TabBar)

效果:

PS:這裡需要用到UIView一個分類的一些屬性,參考http://blog.csdn.net/doubleface999/article/details/79085764,圖示素材等自行上網找或者自己設計,這裡就不提供了。最後在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
複製程式碼