項目中經(jīng)常有tabbar中間有個?的需求,今天整理了一下,PO在這里
整體思路:因為?超出了tabbar的響應(yīng)范圍,想要點擊有響應(yīng),需要重寫view的hitTest方法。所以我們需自定義一個tabbar,添加了一個?,它不是正常的tabbaritem,我把他作為一個button來對待
1)我們需要自定義一個tabbarcontroller,方便移植
2)自定義一個tabbar,用到layoutSubviews方法,更改它原有tabbaritem的frame,通過setter/getter方法添加plusBtn
?3)tabbar定制協(xié)議,讓tabbarcontroller遵循并實現(xiàn)協(xié)議方法,完成點擊plusBtn進入新的界面
4)在tabbar中重寫view的hitTest方法,響應(yīng)點擊超出tabbar的加號按鈕
現(xiàn)在我直接貼出每個文件的具體代碼,以免看亂
1. ? ?自定義TGZTabbarController ,圖1為.h文件

2.圖2為.m文件上半部分內(nèi)容

- (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;
? ? //設(shè)置tabbar的代理
? ? tabBar.TabDelegate=self;
? ? self.viewControllers=@[anva,bnva,cnva,dnva];
? ? //kvc : 如果要修改系統(tǒng)的某些屬性,但被設(shè)置為readonly,就用kvc,setvalue:forkey
? ? [selfsetValue:tabBarforKey:@"tabBar"];
}
#pragma mark - - - - -- - 實現(xiàn)代理協(xié)議? 點擊了加號按鈕 - - - - -
-(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文件內(nèi)容
#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{ //系統(tǒng)方法,只有更改frame時,才能重寫此方法
? ? [super layoutSubviews];//與viewwillappear類似
? ? //1. 設(shè)置plusBtn的位置
? ? self.plusBtn.center = CGPointMake(self.center.x, self.frame.size.height*0.1);
? ? //設(shè)置其他tabbaritem的位置,大小
? ? CGFloattabbaritemwidth =self.frame.size.width/5;
? ? CGFloattabbarindex =0;
? ? for(UIView* viewinself.subviews) {
? ? ? ? Classclass =NSClassFromString(@"UITabBarButton");
? ? ? ? if([viewisKindOfClass:class]) {
? ? ? ? ? ? //設(shè)置位置? ? ? ? ? ? view.frame=CGRectMake(tabbaritemwidth*tabbarindex,CGRectGetMinY(view.frame), tabbaritemwidth,CGRectGetHeight(view.frame));
?? ? ? ? ? //增加索引,只對非?按鈕的其他4個item進行操作
? ? ? ? ? ? tabbarindex += (tabbarindex ==1?2:1);
? ? ? ?}
? ? }
}
#pragma mark? - - -- - - 重寫hitTest方法,響應(yīng)點擊超出tabbar的加號按鈕
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event{
? ? //這是view的點擊事件
? ? if (self.isHidden == NO) { // 當(dāng)前界面 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,通知代理,執(zhí)行代理協(xié)議方法
? ? ? ? [self.TabDelegate DidClickPlusBtnIntabbar:self];
}
效果如圖5

這樣就大功告成了,點擊?彈出一個新的界面!??!類似樣式,都可以這樣操作,代碼里面有詳細(xì)的注釋,可以幫助理解。