前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实践 -实现一款中间凸起的TabBar

实践 -实现一款中间凸起的TabBar

作者头像
進无尽
发布2018-09-12 18:01:46
2K0
发布2018-09-12 18:01:46
举报
文章被收录于专栏:進无尽的文章進无尽的文章

前言

这是看到一篇文章后感觉很有意思于是就把自己的效果改了改实现了一下,文末有原文链接。

效果

实现步骤

  • 自定义一个UITabBar,中心位置放一个按钮,设置按钮的背景图片,按钮一半超出这个自定义的UITabBar。
  • 重写自定义UITabBar 的hitTest 方法,根据点击的位置返回点击的视图是 UITabBar还是 UITabBar上面的按钮。这部分很关键,还要处理点击UITabBar超出试图部分的按钮问题。
  • 使用KVC将自定义UITabBar 赋值给 UITabBarController
  • 在UITabBarController中给自定义UITabBar上面的按钮绑定事件,来联动UITabBarController的事件。

源码解析

自定义UITabBar并重写 hitTest方法
代码语言:javascript
复制
@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+10, normalImage.size.height+10);
    [_centerBtn setImage:normalImage forState:UIControlStateNormal];
    //去除选择时高亮
    _centerBtn.adjustsImageWhenHighlighted = NO;
    //根据图片调整button的位置(图片中心在tabbar的中间最上部,这个时候由于按钮是有一部分超出tabbar的,所以点击无效,要进行处理)
    _centerBtn.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - normalImage.size.width-10)/2.0, - normalImage.size.height/2.0-5, normalImage.size.width+10, normalImage.size.height+10);
    [self addSubview:_centerBtn];
}

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

    //******************    或者使用这个方法     ****************
    
      //判断如果这个新的点是在发布按钮身上,那么处理点击事件最合适的view就是发布按钮
      if ( [self.centerBtn pointInside:point withEvent:event]) {
            return self.centerBtn;
      }else{//如果点不在发布按钮身上,直接让系统处理就可以了
          return [super hitTest:point withEvent:event];
      }
    }
    return view;
}

这里特别介绍一下下面两个方法:

代码语言:javascript
复制
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;

[fromView convertPoint:point toView:toView];
[toView convertPoint:point fromView:fromView];

这两句代码的意思都是将fromView中的点p(40,30)转换为相对toView的坐标。可以看到两段代码的结果是一样的。

处理UITabBarController

注意是 vc2.title=@"医疗"; 而不是 vc2.tabBarItem.title =@"医疗"; 如果是第二种方法,在设置图片为空的时候,Tabbar下面的文字也不会显示了。

代码语言:javascript
复制
 MedicalViewController *vc2=[[MedicalViewController alloc] init];
  vc2.title=@"医疗";
 vc2.tabBarItem.image=[[UIImage imageNamed:@""] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
 vc2.tabBarItem.selectedImage=[[UIImage imageNamed:@""] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
由于UITabBarController的UITabBar属性是readonly,所以无法直接赋值
代码语言:javascript
复制
    _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"];
自定义UITabBar上面的按钮绑定事件,来联动UITabBarController的事件。
代码语言:javascript
复制
 - (void)buttonAction:(UIButton *)button{
      self.selectedIndex = 1;//关联中间按钮
      [self rotationAnimation];
  }

//tabbar选择时的代理
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
  if (tabBarController.selectedIndex == 1){//选中中间的按钮
      [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"];
}

参考文章: https://www.jianshu.com/p/5160a1b48679

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.01.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 效果
  • 实现步骤
  • 源码解析
    • 自定义UITabBar并重写 hitTest方法
      • 处理UITabBarController
        • 由于UITabBarController的UITabBar属性是readonly,所以无法直接赋值
          • 自定义UITabBar上面的按钮绑定事件,来联动UITabBarController的事件。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档