iOS Tabbar中间添加凸起可旋转按钮

栏目: IOS · 发布时间: 5年前

内容简介:最近的项目中有需求在tabbar中间添加凸起按钮,并且点击时按钮要旋转,看了仿闲鱼的凸起,点击后是present出来View,而不是像常规的tabbar上添加一个页面(亲测,闲鱼的超出Tabbar部分点击是没有反应的,这是bug啊,下文对这个问题有详解),所以不符合要求,经过一段摸索最后得的一个比较好的效果,下面看效果图这样实现的效果如下图所示利用KVC赋值

最近的项目中有需求在tabbar中间添加凸起按钮,并且点击时按钮要旋转,看了仿闲鱼的凸起,点击后是present出来View,而不是像常规的tabbar上添加一个页面(亲测,闲鱼的超出Tabbar部分点击是没有反应的,这是bug啊,下文对这个问题有详解),所以不符合要求,经过一段摸索最后得的一个比较好的效果,下面看效果图

iOS Tabbar中间添加凸起可旋转按钮
(本文简书地址: www.jianshu.com/p/5160a1b48…

需求分析

  • tabbar有5个item,每个对应一个页面
  • 中间item为凸起按钮
  • 中间按钮点击后旋转

效果实现

  • 设置5个item 我们一步步来解决这个问题,首先创建MCTabBarController继承UITabBarController,然后和常规一样创建5个item,中间的按钮不设置图片,代码如下
//MCTabBarController.m
//添加子控制器
- (void)addChildViewControllers{
    //图片大小建议32*32
    [self addChildrenViewController:[[ViewController alloc] init] andTitle:@"首页" andImageName:@"tab1"];
    [self addChildrenViewController:[[ViewController alloc] init] andTitle:@"扩展" andImageName:@"tab2"];
    //中间这个不设置东西,只占位
    [self addChildrenViewController:[[ViewController alloc] init] andTitle:@"旋转" andImageName:@""];
    [self addChildrenViewController:[[ViewController alloc] init] andTitle:@"发现" andImageName:@"tab3"];
    [self addChildrenViewController:[[ViewController alloc] init] andTitle:@"我的" andImageName:@"tab4"];
}

- (void)addChildrenViewController:(UIViewController *)childVC andTitle:(NSString *)title andImageName:(NSString *)imageName{
    childVC.tabBarItem.image = [UIImage imageNamed:imageName];
 // 选中的颜色由tabbar的tintColor决定
    childVC.tabBarItem.selectedImage =  [UIImage imageNamed:imageName];
    childVC.title = title;
    
    BaseNavigationController *baseNav = [[BaseNavigationController alloc] initWithRootViewController:childVC];
    
    [self addChildViewController:baseNav];
}
复制代码

这样实现的效果如下图所示

iOS Tabbar中间添加凸起可旋转按钮
  • 添加凸起按钮 我们可以在UITabBar上添加我们的凸起按钮,让他的位置在没有设置的中间按钮偏上,按钮的点击和中间按钮点击绑定,这里直接在MCTabBarController.m中添加会有问题 1、因为凸起按钮的frame超出了UITabBar的frame,这样超出的区域点击按钮会没有响应(图二红框区域),原因和解决办法详情参考我的这篇 iOS UIButton 点击无响应的解决办法 ,由于要在UITabBar上添加凸起按钮,并且处理点击无效的问题,所以这里创建了MCTabBar继承UITabBar
    iOS Tabbar中间添加凸起可旋转按钮
    2、由于UITabBar是readonly的,所以我们不能直接对他进行赋值,这里利用KVC访问私有变量将MCTabBar赋值给"tabBar" 具体实现 MCTabBar
#import <UIKit/UIKit.h>

@interface MCTabBar : UITabBar
@property (nonatomic, strong) UIButton *centerBtn; //中间按钮
@end
复制代码
@implementation MCTabBar
- (instancetype)init{
    if (self = [super init]){
        [self initView];
    }
    return self;
}

- (void)initView{
    _centerBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    //  设定button大小为适应图片
    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;
    //根据图片调整button的位置(图片中心在tabbar的中间最上部,这个时候由于按钮是有一部分超出tabbar的,所以点击无效,要进行处理)
    _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];
}

//处理超出区域点击无效的问题
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    if (self.hidden){ //如果tabbar隐藏了,那么直接执行系统方法
        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];
        }
    }
}
复制代码

利用KVC赋值

//MCTabBarController.m
- (void)viewDidLoad {
    [super viewDidLoad];
    
    _mcTabbar = [[MCTabBar alloc] init];
     [_mcTabbar.centerBtn addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
    //选中时的颜色
    _mcTabbar.tintColor = [UIColor colorWithRed:27.0/255.0 green:118.0/255.0 blue:208/255.0 alpha:1];
   //透明设置为NO,显示白色,view的高度到tabbar顶部截止,YES的话到底部
    _mcTabbar.translucent = NO;
    //利用KVC 将自己的tabbar赋给系统tabBar
    [self setValue:_mcTabbar forKeyPath:@"tabBar"];
   self.selectItem = 0; //默认选中第一个
    self.delegate = self;
    [self addChildViewControllers];
}
复制代码
  • 点击旋转 在中间按钮的点击事件执行时旋转第二个index,然后执行旋转动画, 在tabbar的代理事件中监听旋中中间按钮的事件,然后执行旋转动画,其他按钮则移除动画,代码如下
- (void)buttonAction:(UIButton *)button{
  self.selectedIndex = 2;//关联中间按钮
    if (self.selectItem != 2){ //如果是选中的旋转按钮则不再次进行旋转
        [self rotationAnimation];
    }
    self.selectItem = 2;
}

//tabbar选择时的代理
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
    if (tabBarController.selectedIndex == 2){//选中中间的按钮
       if (self.selectItem != 2){
             [self rotationAnimation];
        }
    }else {
        [_mcTabbar.centerBtn.layer removeAllAnimations];
    }
}
//旋转动画
- (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上移的问题。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

ANSI Common Lisp

ANSI Common Lisp

Paul Graham / Prentice Hall / 1995-11-12 / USD 116.40

For use as a core text supplement in any course covering common LISP such as Artificial Intelligence or Concepts of Programming Languages. Teaching students new and more powerful ways of thinking abo......一起来看看 《ANSI Common Lisp》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具