自定義中間按鈕可旋轉(zhuǎn)可突出視圖Tabbar

前言

小編最近在開發(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

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

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

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