自定义中间按钮可旋转可突出视图Tabbar

前言

小编最近在开发过程中遇到一个这样的需求,就是需要tabbar中间的按钮突出原来的视图,并且中间按钮可以根据需要旋转,废话不多说,先上效果图:


如何实现

1.自定义tabbar样式

建立一个类继承UITabBar,并在这个类中设置中间按钮的样式,如下:

#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];
//    设定button大小为适应图片
    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];
    
//    去除选择时高亮
    _centerBtn.adjustsImageWhenHighlighted = NO;
//---------------------------根据需要选择是否保留和设置-------------------------------
//    调整图片突出的位置
    _centerBtn.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - normalImage.size.width)/2.0, - normalImage.size.height/2.0, normalImage.size.width, normalImage.size.height);
//    给按钮设置边框
//    _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 颜色转化为图片
- (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

因为按钮有一部分是突出来的,所以需要判定一下,如下:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (self.hidden) {
        return [super hitTest:point withEvent:event];
    }else {
//        转换坐标
        CGPoint tempPoint = [self.centerBtn convertPoint:point fromView:self];
//        判断点击的点是否在按钮区域内
        if (CGRectContainsPoint(self.centerBtn.bounds, tempPoint)) {
//            返回按钮
            return _centerBtn;
        }else {
            return [super hitTest:point withEvent:event];
        }
    }
}

2.添加子视图

建立一个TabbarController继承UITabBarController,将需要展示的子视图添加进去,如下:

#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];
//    选中时的颜色
    [self setValue:_tabbar forKey:@"tabBar"];
    
    [self loadViewControllers];
}

- (void)loadViewControllers {
//    中间为设置的图片视图
    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];
//------------------------------根据需求设置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.添加动画

给tabbar的中间按钮添加动画,这个步骤需要绑定tabbar的代理,如下:

- (void)buttonAction:(UIButton *)button {
    self.selectedIndex = 2;//关联中间按钮
    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];
    }
}
//旋转动画
- (void)rotationAnimation{
//    继续旋转
    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 {
//        开始旋转
        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;
}

/**
 暂停动画
 @param isCurrent 是否暂停到当前状态
 */
- (void)pauseAnimationInCurrentState:(BOOL)isCurrent{
    if (isCurrent) {
        //1.取出当前时间,转成动画暂停的时间
        CFTimeInterval pauseTime = [_tabbar.centerBtn.layer convertTime:CACurrentMediaTime() fromLayer:nil];
        
        //2.设置动画的时间偏移量,指定时间偏移量的目的是让动画定格在该时间点的位置
        _tabbar.centerBtn.layer.timeOffset = pauseTime;
        
        //3.将动画的运行速度设置为0, 默认的运行速度是1.0
        _tabbar.centerBtn.layer.speed = 0;

    }else {
        [_tabbar.centerBtn.layer removeAllAnimations];
    }
    _isAnimation = NO;
}

当上述所有步骤都完成之后,大功告成。即可出现上面显示的效果。

希望这篇文章对各位看官有所帮助,Demo下载地址:Demo

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,270评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,489评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,630评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,906评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,928评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,718评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,442评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,345评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,802评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,984评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,117评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,810评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,462评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,011评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,139评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,377评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,060评论 2 355

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,107评论 4 62
  • 说好今晚去找山体新生的,可是竟然又要打扫卫生,真烦透了!明天还要上课,真的很烦啊(⋟﹏⋞) 我还有计算机二级没考,...
    我爱旦阅读 148评论 0 1
  • 2012年4月份,我失恋了,突然感觉自己什么都没有了,工作也是自己不喜欢的,喜欢的人也从我的世界走出了,但是我竟然...
    虎叔2018阅读 358评论 0 3
  • 最近,小F突然问我喜欢什么样儿的姑娘。我一时语塞,竟答不上来。 细细想,对于这个问题,我自己本身就没有一个比较清晰...
    质量过关阅读 207评论 0 0