效果:
PS:这里需要用到UIView一个分类的一些属性,参考/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 @end11 12 @interface MyTabBar : UITabBar13 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 { 27if(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]; 3940 self.addButton = addBtn; 41} 42return self; 43 } 44 45 //响应中间“+”按钮点击事件 46 -(void)addBtnDidClick 47 { 48if([self.myTabBarDelegate respondsToSelector:@selector(addButtonClick:)]) 49{ 50 [self.myTabBarDelegate addButtonClick:self]; 51} 52 } 53 54 -(void)layoutSubviews 55 { 56[super layoutSubviews]; 5758//去掉TabBar上部的横线 59for (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} 6768//设置“+”按钮的位置 69self.addButton.centerX = self.centerX; 70self.addButton.centerY = self.height * 0.5 - 1.5 * AddButtonMargin; 71//设置“+”按钮的大小为图片的大小 72self.addButton.size = CGSizeMake(self.addButton.currentBackgroundImage.size.width, self.addButton.currentBackgroundImage.size.height); 7374//创建并设置“+”按钮下方的文本为“添加” 75UILabel *addLbl = [[UILabel alloc] init]; 76addLbl.text = @"添加"; 77addLbl.font = [UIFont systemFontOfSize:10]; 78addLbl.textColor = [UIColor grayColor]; 79[addLbl sizeToFit]; 80 81//设置“添加”label的位置 82addLbl.centerX = self.addButton.centerX; 83addLbl.centerY = CGRectGetMaxY(self.addButton.frame) + 0.5 * AddButtonMargin + 0.5; 8485[self addSubview:addLbl]; 8687self.addLabel = addLbl; 8889int btnIndex = 0; 90//系统自带的按钮类型是UITabBarButton,找出这些类型的按钮,然后重新排布位置,空出中间的位置 91Class class = NSClassFromString(@"UITabBarButton"); 92for (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 {113114//这一个判断是关键,不判断的话push到其他页面,点击“+”按钮的位置也是会有反应的,这样就不好了115//self.isHidden == NO 说明当前页面是有TabBar的,那么肯定是在根控制器页面116//在根控制器页面,那么我们就需要判断手指点击的位置是否在“+”按钮或“添加”标签上117//是的话让“+”按钮自己处理点击事件,不是的话让系统去处理点击事件就可以了118if (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 else137 {//如果点不在“+”按钮身上,直接让系统处理就可以了138 139 return [super hitTest:point withEvent:event];140 }141}142else143{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 : UITabBarController4 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 MyTabBarController10 11 - (void)viewDidLoad {12[super viewDidLoad];13// Do any additional setup after loading the view.1415//设置TabBar上第一个Item(明细)选中时的图片16UIImage *listActive = [UIImage imageNamed:@"ListIcon - Active(blue)"];17UITabBarItem *listItem = self.tabBar.items[0];18//始终按照原图片渲染19listItem.selectedImage = [listActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];22//设置TabBar上第二个Item(报表)选中时的图片23UIImage *chartActive = [UIImage imageNamed:@"ChartIcon - Active(blue)"];24UITabBarItem *chartItem = self.tabBar.items[1];25//始终按照原图片渲染26chartItem.selectedImage = [chartActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];2728//创建自定义TabBar29MyTabBar *myTabBar = [[MyTabBar alloc] init];30myTabBar.myTabBarDelegate = self;3132//利用KVC替换默认的TabBar33[self setValue:myTabBar forKey:@"tabBar"];34 }35 36 37 -(void)viewDidLayoutSubviews38 {39[super viewDidLayoutSubviews];40//设置TabBar的TintColor41self.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 - MyTabBarDelegate52 -(void)addButtonClick:(MyTabBar *)tabBar53 {54//测试中间“+”按钮是否可以点击并处理事件55UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"test" message:@"Test" preferredStyle:UIAlertControllerStyleAlert];56UIAlertAction *action = [UIAlertAction actionWithTitle:@"test" style:UIAlertActionStyleDefault handler:nil];57[controller addAction:action];58[self presentViewController:controller animated:YES completion:nil];5960 }61 62 @end
原文链接:/guitarandcode/p/5759208.html