项目中经常有tabbar中间有个➕的需求,今天整理了一下,PO在这里
整体思路:因为➕超出了tabbar的响应范围,想要点击有响应,需要重写view的hitTest方法。所以我们需自定义一个tabbar,添加了一个➕,它不是正常的tabbaritem,我把他作为一个button来对待
1)我们需要自定义一个tabbarcontroller,方便移植
2)自定义一个tabbar,用到layoutSubviews方法,更改它原有tabbaritem的frame,通过setter/getter方法添加plusBtn
3)tabbar定制协议,让tabbarcontroller遵循并实现协议方法,完成点击plusBtn进入新的界面
4)在tabbar中重写view的hitTest方法,响应点击超出tabbar的加号按钮
现在我直接贴出每个文件的具体代码,以免看乱
1. 自定义TGZTabbarController ,图1为.h文件
2.图2为.m文件上半部分内容
- (void)createUI{
AViewController * avc = [[AViewController alloc]init];
BViewController * bvc = [[BViewController alloc]init];
CViewController * cvc = [[CViewController alloc]init];
DViewController * dvc = [[DViewController alloc]init];
avc.view.backgroundColor = [UIColor yellowColor];
bvc.view.backgroundColor = [UIColor brownColor];
cvc.view.backgroundColor = [UIColor greenColor];
dvc.view.backgroundColor = [UIColor purpleColor];
UINavigationController * anva = [[UINavigationController alloc]initWithRootViewController:avc];
UINavigationController * bnva = [[UINavigationController alloc]initWithRootViewController:bvc];
UINavigationController * cnva = [[UINavigationController alloc]initWithRootViewController:cvc];
UINavigationController * dnva = [[UINavigationController alloc]initWithRootViewController:dvc];
avc.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemMore tag:1];
avc.tabBarItem.title = @"首页";
bvc.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemSearch tag:2];
bvc.tabBarItem.title = @"喜欢";
cvc.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemHistory tag:3];
cvc.tabBarItem.title = @"历史";
dvc.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemContacts tag:4];
dvc.tabBarItem.title = @"我的";
TGZTabbar* tabBar = [[TGZTabbaralloc]init];
//取消tabbar的透明效果
tabBar.translucent=NO;
//设置tabbar的代理
tabBar.TabDelegate=self;
self.viewControllers=@[anva,bnva,cnva,dnva];
//kvc : 如果要修改系统的某些属性,但被设置为readonly,就用kvc,setvalue:forkey
[selfsetValue:tabBarforKey:@"tabBar"];
}
#pragma mark - - - - -- - 实现代理协议 点击了加号按钮 - - - - -
-(void)DidClickPlusBtnIntabbar:(TGZTabbar*)tabbar{
//在这里写点击了加号按钮,需要处理的事件
UIViewController * addvc = [[UIViewController alloc]init];
addvc.view.backgroundColor = [UIColor cyanColor];
[self presentViewController:addvc animated:YES completion:nil];
}
3. 自定义TGZTabbar,图3为.h文件
4. 下面为TGZTabbar.m文件内容
#import "TGZTabbar.h"
@interface TGZTabbar ()
@property (nonatomic,strong)UIButton *plusBtn;
@end
@implementation TGZTabbar
@synthesize plusBtn = _plusBtn; //重写setter和getter方法时,需要加上这句话
#pragma mark - -- - lifeCycle 确保每次都添加PlusBtn
-(instancetype)initWithFrame:(CGRect)frame{
if(self= [superinitWithFrame:frame]) {
[selfaddSubview:self.plusBtn];//添加➕按钮
}
return self;
}
#pragma mark - - - -- private method
//重新布局tabbaritem,
-(void)layoutSubviews{ //系统方法,只有更改frame时,才能重写此方法
[super layoutSubviews];//与viewwillappear类似
//1. 设置plusBtn的位置
self.plusBtn.center = CGPointMake(self.center.x, self.frame.size.height*0.1);
//设置其他tabbaritem的位置,大小
CGFloattabbaritemwidth =self.frame.size.width/5;
CGFloattabbarindex =0;
for(UIView* viewinself.subviews) {
Classclass =NSClassFromString(@"UITabBarButton");
if([viewisKindOfClass:class]) {
//设置位置 view.frame=CGRectMake(tabbaritemwidth*tabbarindex,CGRectGetMinY(view.frame), tabbaritemwidth,CGRectGetHeight(view.frame));
//增加索引,只对非➕按钮的其他4个item进行操作
tabbarindex += (tabbarindex ==1?2:1);
}
}
}
#pragma mark - - -- - - 重写hitTest方法,响应点击超出tabbar的加号按钮
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event{
//这是view的点击事件
if (self.isHidden == NO) { // 当前界面 tabBar显示
CGPointnewPoint = [selfconvertPoint:pointtoView:self.plusBtn];
if( [self.plusBtnpointInside:newPointwithEvent:event]) {// 点 属于按钮范围
returnself.plusBtn;
}else{
return[superhitTest:pointwithEvent:event];
}
}else{
return[superhitTest:pointwithEvent:event];
}
}
#pragma mark - - - - - - plusBtn的setter /getter方法
- (void)setPlusBtn:(UIButton*)plusBtn{
_plusBtn= plusBtn;
}
- (UIButton*)plusBtn{
if(!_plusBtn) {
_plusBtn= [[UIButtonalloc]init];
[_plusBtn setImage:[UIImage imageNamed:@"addImage"] forState:UIControlStateNormal];
// [_plusBtn setImage:[UIImage imageNamed:@""] forState:UIControlStateHighlighted];
_plusBtn.frame = CGRectMake(0, 0, _plusBtn.imageView.image.size.width, _plusBtn.imageView.image.size.height);
_plusBtn.frame=CGRectMake(0,0,80,80);//尺寸具体看项目需求
[_plusBtn addTarget:self action:@selector(respondsToPlusButton) forControlEvents:UIControlEventTouchUpInside];
}
return _plusBtn;
}
#pragma mark - - -- - event responds
- (void)respondsToPlusButton{
//点击了Plusbtn,通知代理,执行代理协议方法
[self.TabDelegate DidClickPlusBtnIntabbar:self];
}
效果如图5
这样就大功告成了,点击➕弹出一个新的界面!!!类似样式,都可以这样操作,代码里面有详细的注释,可以帮助理解。