前言
小編最近在開發(fā)過程中遇到一個(gè)這樣的需求,就是需要tabbar中間的按鈕突出原來的視圖,并且中間按鈕可以根據(jù)需要旋轉(zhuǎn),廢話不多說,先上效果圖:

如何實(shí)現(xiàn)
1.自定義tabbar樣式
建立一個(gè)類繼承UITabBar,并在這個(gè)類中設(shè)置中間按鈕的樣式,如下:
#import <UIKit/UIKit.h>
@interface TabBar : UITabBar
@property(nonatomic, strong) UIButton *centerBtn;//中間按鈕
@end
//---------------------------------------------------------------
#import "TabBar.h"
@implementation TabBar
- (instancetype)init
{
self = [super init];
if (self) {
[self initView];
}
return self;
}
- (void)initView
{
_centerBtn = [UIButton buttonWithType:UIButtonTypeCustom];
// 設(shè)定button大小為適應(yīng)圖片
UIImage *normalImage = [UIImage imageNamed:@"加"];
_centerBtn.frame = CGRectMake((UIScreen.mainScreen.bounds.size.width - normalImage.size.width)/2, 0, normalImage.size.width, normalImage.size.height);
[_centerBtn setImage:normalImage forState:UIControlStateNormal];
// 去除選擇時(shí)高亮
_centerBtn.adjustsImageWhenHighlighted = NO;
//---------------------------根據(jù)需要選擇是否保留和設(shè)置-------------------------------
// 調(diào)整圖片突出的位置
_centerBtn.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - normalImage.size.width)/2.0, - normalImage.size.height/2.0, normalImage.size.width, normalImage.size.height);
// 給按鈕設(shè)置邊框
// _centerBtn.layer.masksToBounds = YES;
// _centerBtn.layer.cornerRadius = _centerBtn.frame.size.width / 2;
// _centerBtn.layer.borderWidth = 5;
// _centerBtn.layer.borderColor = [UIColor whiteColor].CGColor;
CGFloat borderWidth = 5;
UIView *btnLayerView = [[UIView alloc]initWithFrame:(CGRect){_centerBtn.frame.origin.x - borderWidth, _centerBtn.frame.origin.y - borderWidth, _centerBtn.frame.size.width + 2 * borderWidth, _centerBtn.frame.size.height + 2 * borderWidth}];
btnLayerView.backgroundColor = [UIColor whiteColor];
btnLayerView.layer.masksToBounds = YES;
btnLayerView.layer.cornerRadius = btnLayerView.frame.size.width / 2;
[self addSubview:btnLayerView];
//------------------------------------------------------------------------------
[self addSubview:_centerBtn];
// 去除Tabbar上方黑線
[self setBackgroundImage:[self ChangeUIColorToUIImage:[UIColor whiteColor]]];
[self setShadowImage:[self ChangeUIColorToUIImage:[UIColor whiteColor]]];
}
#pragma mark 顏色轉(zhuǎn)化為圖片
- (UIImage *)ChangeUIColorToUIImage: (UIColor *) color
{
CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
CGContextFillRect(context, rect);
UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return theImage;
}
}
@end
因?yàn)榘粹o有一部分是突出來的,所以需要判定一下,如下:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if (self.hidden) {
return [super hitTest:point withEvent:event];
}else {
// 轉(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;
}else {
return [super hitTest:point withEvent:event];
}
}
}
2.添加子視圖
建立一個(gè)TabbarController繼承UITabBarController,將需要展示的子視圖添加進(jìn)去,如下:
#import "TabBarController.h"
#import "TabBar.h"
@interface TabBarController ()<UITabBarControllerDelegate>
@property (nonatomic, strong) TabBar *tabbar;
@property (assign, nonatomic) BOOL isAnimation;
@end
@implementation TabBarController
- (void)viewDidLoad {
[super viewDidLoad];
[self loadUI];
self.delegate = self;
_isAnimation = NO;
}
- (void)loadUI {
_tabbar = [TabBar new];
[_tabbar.centerBtn addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
// 選中時(shí)的顏色
[self setValue:_tabbar forKey:@"tabBar"];
[self loadViewControllers];
}
- (void)loadViewControllers {
// 中間為設(shè)置的圖片視圖
NSArray *titles = @[@"Title1",@"Title2",@"",@"Title3",@"Title4"];
NSMutableArray *clts = [NSMutableArray array];
for (int i = 0; i < titles.count; i++) {
UIViewController *vc = [UIViewController new];
vc.title = titles[i];
//------------------------------根據(jù)需求設(shè)置Tabbar其他iTem格式--------------------------------
[vc.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor grayColor], NSFontAttributeName:[UIFont systemFontOfSize:13]} forState:UIControlStateNormal];
[vc.tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor colorWithRed:18/255.0 green:150/255.0 blue:219/255.0 alpha:1], NSFontAttributeName:[UIFont systemFontOfSize:13]} forState:UIControlStateSelected];
vc.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -15);
CGFloat red = (arc4random() % 255) / 255.0;
CGFloat green = (arc4random() % 255) / 255.0;
CGFloat blue = (arc4random() % 255) / 255.0;
vc.view.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1];
//----------------------------------------------------------------------------------------
[clts addObject:vc];
}
self.viewControllers = clts;
}
3.添加動(dòng)畫
給tabbar的中間按鈕添加動(dòng)畫,這個(gè)步驟需要綁定tabbar的代理,如下:
- (void)buttonAction:(UIButton *)button {
self.selectedIndex = 2;//關(guān)聯(lián)中間按鈕
if ([_tabbar.centerBtn.layer.animationKeys containsObject:@"key"] && _isAnimation == YES) {
[self pauseAnimationInCurrentState:YES];
}else {
[self rotationAnimation];
}
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if (tabBarController.selectedIndex != 2 && _isAnimation == YES){//選中中間的按鈕
[self pauseAnimationInCurrentState:YES];
}
}
//旋轉(zhuǎn)動(dòng)畫
- (void)rotationAnimation{
// 繼續(xù)旋轉(zhuǎn)
if ([_tabbar.centerBtn.layer.animationKeys containsObject:@"key"]) {
CFTimeInterval pauseTime = _tabbar.centerBtn.layer.timeOffset;
CFTimeInterval begin = CACurrentMediaTime() - pauseTime;
[_tabbar.centerBtn.layer setTimeOffset:0];
[_tabbar.centerBtn.layer setBeginTime:begin];
_tabbar.centerBtn.layer.speed = 1;
}else {
// 開始旋轉(zhuǎn)
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2.0];
rotationAnimation.duration = 2.0;
rotationAnimation.repeatCount = HUGE;
[_tabbar.centerBtn.layer addAnimation:rotationAnimation forKey:@"key"];
}
_isAnimation = YES;
}
/**
暫停動(dòng)畫
@param isCurrent 是否暫停到當(dāng)前狀態(tài)
*/
- (void)pauseAnimationInCurrentState:(BOOL)isCurrent{
if (isCurrent) {
//1.取出當(dāng)前時(shí)間,轉(zhuǎn)成動(dòng)畫暫停的時(shí)間
CFTimeInterval pauseTime = [_tabbar.centerBtn.layer convertTime:CACurrentMediaTime() fromLayer:nil];
//2.設(shè)置動(dòng)畫的時(shí)間偏移量,指定時(shí)間偏移量的目的是讓動(dòng)畫定格在該時(shí)間點(diǎn)的位置
_tabbar.centerBtn.layer.timeOffset = pauseTime;
//3.將動(dòng)畫的運(yùn)行速度設(shè)置為0, 默認(rèn)的運(yùn)行速度是1.0
_tabbar.centerBtn.layer.speed = 0;
}else {
[_tabbar.centerBtn.layer removeAllAnimations];
}
_isAnimation = NO;
}
當(dāng)上述所有步驟都完成之后,大功告成。即可出現(xiàn)上面顯示的效果。
希望這篇文章對(duì)各位看官有所幫助,Demo下載地址:Demo