iOS Tabbar中間添加凸起可旋轉(zhuǎn)按鈕

##前言

>最近的項(xiàng)目中有需求在tabbar中間添加凸起按鈕,并且點(diǎn)擊時按鈕要旋轉(zhuǎn),看了仿斗魚的凸起,點(diǎn)擊后是present出來View,而不是像常規(guī)的tabbar上添加一個頁面,所以不符合要求,經(jīng)過一段摸索最后得的一個比較好的效果

##需求分析

* tabbar有5個item,每個對應(yīng)一個頁面

* 中間item為凸起按鈕

* 中間按鈕點(diǎn)擊后旋轉(zhuǎn)

##效果實(shí)現(xiàn)

* 設(shè)置5個item

我們一步步來解決這個問題,首先創(chuàng)建MCTabBarController繼承UITabBarController,然后和常規(guī)一樣創(chuàng)建5個item,中間的按鈕不設(shè)置圖片,代碼如下

//MCTabBarController.m

//添加子控制器

-?(void)addChildViewControllers{

//圖片大小建議32*32

[self?addChildrenViewController:[[ViewController?alloc]?init]?andTitle:@"首頁"andImageName:@"tab1_n"andSelectImage:@"tab1_p"];

[self?addChildrenViewController:[[ViewController?alloc]?init]?andTitle:@"擴(kuò)展"andImageName:@"tab2_n"andSelectImage:@"tab2_p"];

//中間這個不設(shè)置東西,只占位

[self?addChildrenViewController:[[ViewController?alloc]?init]?andTitle:@"旋轉(zhuǎn)"andImageName:@""andSelectImage:@""];

[self?addChildrenViewController:[[ViewController?alloc]?init]?andTitle:@"發(fā)現(xiàn)"andImageName:@"tab3_n"andSelectImage:@"tab3_p"];

[self?addChildrenViewController:[[ViewController?alloc]?init]?andTitle:@"我"andImageName:@"tab4_n"andSelectImage:@"tab4_p"];

}

-?(void)addChildrenViewController:(UIViewController?*)childVC?andTitle:(NSString?*)title?andImageName:(NSString?*)imageName?andSelectImage:(NSString?*)selectedImage{

childVC.tabBarItem.image?=?[UIImage?imageNamed:imageName];

childVC.tabBarItem.selectedImage?=??[UIImage?imageNamed:selectedImage];

childVC.title?=?title;

BaseNavigationController?*baseNav?=?[[BaseNavigationController?alloc]?initWithRootViewController:childVC];

[self?addChildViewController:baseNav];

}

這樣實(shí)現(xiàn)的效果如下圖所示

[圖一.png]

* 添加凸起按鈕

我們可以在UITabBar上添加我們的凸起按鈕,讓他的位置在沒有設(shè)置的中間按鈕偏上,按鈕的點(diǎn)擊和中間按鈕點(diǎn)擊綁定,這里直接在MCTabBarController.m中添加會有問題

1、因?yàn)橥蛊鸢粹o的frame超出了UITabBar的frame,這樣超出的區(qū)域點(diǎn)擊按鈕會沒有響應(yīng)(圖二紅框區(qū)域),原因和解決辦法詳情參考我的這篇[iOS UIButton 點(diǎn)擊無響應(yīng)的解決辦法],由于要在UITabBar上添加凸起按鈕,并且處理點(diǎn)擊無效的問題,所以這里創(chuàng)建了MCTabBar繼承UITabBar

[圖二.png]

2、由于UITabBar是readonly的,所以我們不能直接對他進(jìn)行賦值,這里利用KVC訪問私有變量將MCTabBar賦值給"tabBar"

**具體實(shí)現(xiàn)**

MCTabBar

```

#import

@interfaceMCTabBar?:?UITabBar

@property?(nonatomic,?strong)?UIButton?*centerBtn;//中間按鈕

@end

```

```

@implementation?MCTabBar

-?(instancetype)init{

if(self?=?[superinit]){

[self?initView];

}

returnself;

}

-?(void)initView{

_centerBtn?=?[UIButton?buttonWithType:UIButtonTypeCustom];

//??設(shè)定button大小為適應(yīng)圖片

UIImage?*normalImage?=?[UIImage?imageNamed:@"tabbar_add"];

_centerBtn.frame?=?CGRectMake(0,0,?normalImage.size.width,?normalImage.size.height);

[_centerBtn?setImage:normalImage?forState:UIControlStateNormal];

//去除選擇時高亮

_centerBtn.adjustsImageWhenHighlighted?=?NO;

//根據(jù)圖片調(diào)整button的位置(圖片中心在tabbar的中間最上部,這個時候由于按鈕是有一部分超出tabbar的,所以點(diǎn)擊無效,要進(jìn)行處理)

_centerBtn.frame?=?CGRectMake(([UIScreen?mainScreen].bounds.size.width?-?normalImage.size.width)/2.0,?-?normalImage.size.height/2.0,?normalImage.size.width,?normalImage.size.height);

[self?addSubview:_centerBtn];

}

//處理超出區(qū)域點(diǎn)擊無效的問題

-?(UIView?*)hitTest:(CGPoint)point?withEvent:(UIEvent?*)event{

UIView?*view?=?[superhitTest:point?withEvent:event];

if(view?==?nil){

//轉(zhuǎn)換坐標(biāo)

CGPoint?tempPoint?=?[self.centerBtn?convertPoint:point?fromView:self];

//判斷點(diǎn)擊的點(diǎn)是否在按鈕區(qū)域內(nèi)

if(CGRectContainsPoint(self.centerBtn.bounds,?tempPoint)){

//返回按鈕

return_centerBtn;

}

}

returnview;

}

```

利用KVC賦值

```

//MCTabBarController.m

-?(void)viewDidLoad?{

[superviewDidLoad];

_mcTabbar?=?[[MCTabBar?alloc]?init];

[_mcTabbar.centerBtn?addTarget:self?action:@selector(buttonAction:)?forControlEvents:UIControlEventTouchUpInside];

//選中時的顏色

_mcTabbar.tintColor?=?[UIColor?colorWithRed:27.0/255.0green:118.0/255.0blue:208/255.0alpha:1];

//透明設(shè)置為NO,顯示白色,view的高度到tabbar頂部截止,YES的話到底部

_mcTabbar.translucent?=?NO;

//利用KVC?將自己的tabbar賦給系統(tǒng)tabBar

[self?setValue:_mcTabbar?forKeyPath:@"tabBar"];

self.delegate?=?self;

[self?addChildViewControllers];

}

```

* 點(diǎn)擊旋轉(zhuǎn)

在中間按鈕的點(diǎn)擊事件執(zhí)行時旋轉(zhuǎn)第二個index,然后執(zhí)行旋轉(zhuǎn)動畫,

在tabbar的代理事件中監(jiān)聽旋中中間按鈕的事件,然后執(zhí)行旋轉(zhuǎn)動畫,其他按鈕則移除動畫,代碼如下

```

-?(void)buttonAction:(UIButton?*)button{

self.selectedIndex?=2;//關(guān)聯(lián)中間按鈕

[self?rotationAnimation];

}

//tabbar選擇時的代理

-?(void)tabBarController:(UITabBarController?*)tabBarController?didSelectViewController:(UIViewController?*)viewController{

if(tabBarController.selectedIndex?==2){//選中中間的按鈕

[self?rotationAnimation];

}else{

[_mcTabbar.centerBtn.layer?removeAllAnimations];

}

}

//旋轉(zhuǎn)動畫

-?(void)rotationAnimation{

CABasicAnimation?*rotationAnimation?=?[CABasicAnimation?animationWithKeyPath:@"transform.rotation.z"];

rotationAnimation.toValue?=?[NSNumber?numberWithFloat:M_PI*2.0];

rotationAnimation.duration?=3.0;

rotationAnimation.repeatCount?=?HUGE;

[_mcTabbar.centerBtn.layer?addAnimation:rotationAnimation?forKey:@"key"];

}

```

* 其他

這里寫了BaseNavigationController繼承自UINavigationController,處理了push后隱藏底部UITabBar的情況,并解決了iPhonX上push時UITabBar上移的問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容