zoukankan      html  css  js  c++  java
  • iOS开发之实现TabBar中间凸起“+”按钮(自定义TabBar)

    参考:http://www.jianshu.com/p/46f61bc7a938,https://github.com/Mringkang/KBCustomCenterTabbar

    效果:

    PS:这里需要用到UIView一个分类的一些属性,参考http://www.cnblogs.com/guitarandcode/p/5758995.html   ,图标素材等自行上网找或者自己设计,这里就不提供了。最后在StoryBoard中选择TabBarController对应下面自定义的TabBarController即可

    自定义TabBar

     MyTabBar.h

     1 #import <UIKit/UIKit.h>
     2 
     3 @class MyTabBar;
     4 
     5 //MyTabBar的代理必须实现addButtonClick,以响应中间“+”按钮的点击事件
     6 @protocol MyTabBarDelegate <NSObject>
     7 
     8 -(void)addButtonClick:(MyTabBar *)tabBar;
     9 
    10 @end
    11 
    12 @interface MyTabBar : UITabBar
    13 
    14 //指向MyTabBar的代理
    15 @property (nonatomic,weak) id<MyTabBarDelegate> myTabBarDelegate;
    16 
    17 @end

    MyTabBar.m

      1 #import "MyTabBar.h"
      2 #import "UIView+Category.h"
      3 
      4 #define AddButtonMargin 10
      5 
      6 @interface MyTabBar()
      7 
      8 //指向中间“+”按钮
      9 @property (nonatomic,weak) UIButton *addButton;
     10 //指向“添加”标签
     11 @property (nonatomic,weak) UILabel *addLabel;
     12 
     13 @end
     14 
     15 @implementation MyTabBar
     16 
     17 /*
     18 // Only override drawRect: if you perform custom drawing.
     19 // An empty implementation adversely affects performance during animation.
     20 - (void)drawRect:(CGRect)rect {
     21     // Drawing code
     22 }
     23 */
     24 
     25 -(instancetype)initWithFrame:(CGRect)frame
     26 {
     27     if(self = [super initWithFrame:frame])
     28     {
     29         //创建中间“+”按钮
     30         UIButton *addBtn = [[UIButton alloc] init];
     31         //设置默认背景图片
     32         [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon"] forState:UIControlStateNormal];
     33         //设置按下时背景图片
     34         [addBtn setBackgroundImage:[UIImage imageNamed:@"AddButtonIcon-Active"] forState:UIControlStateHighlighted];
     35         //添加响应事件
     36         [addBtn addTarget:self action:@selector(addBtnDidClick) forControlEvents:UIControlEventTouchUpInside];
     37         //将按钮添加到TabBar
     38         [self addSubview:addBtn];
     39         
     40         self.addButton = addBtn;
     41     }
     42     return self;
     43 }
     44 
     45 //响应中间“+”按钮点击事件
     46 -(void)addBtnDidClick
     47 {
     48     if([self.myTabBarDelegate respondsToSelector:@selector(addButtonClick:)])
     49     {
     50         [self.myTabBarDelegate addButtonClick:self];
     51     }
     52 }
     53 
     54 -(void)layoutSubviews
     55 {
     56     [super layoutSubviews];
     57     
     58     //去掉TabBar上部的横线
     59     for (UIView *view in self.subviews)
     60     {
     61         if ([view isKindOfClass:[UIImageView class]] && view.bounds.size.height <= 1)   //横线的高度为0.5
     62         {
     63             UIImageView *line = (UIImageView *)view;
     64             line.hidden = YES;
     65         }
     66     }
     67     
     68     //设置“+”按钮的位置
     69     self.addButton.centerX = self.centerX;
     70     self.addButton.centerY = self.height * 0.5 - 1.5 * AddButtonMargin;
     71     //设置“+”按钮的大小为图片的大小
     72     self.addButton.size = CGSizeMake(self.addButton.currentBackgroundImage.size.width, self.addButton.currentBackgroundImage.size.height);
     73     
     74     //创建并设置“+”按钮下方的文本为“添加”
     75     UILabel *addLbl = [[UILabel alloc] init];
     76     addLbl.text = @"添加";
     77     addLbl.font = [UIFont systemFontOfSize:10];
     78     addLbl.textColor = [UIColor grayColor];
     79     [addLbl sizeToFit];
     80 
     81     //设置“添加”label的位置
     82     addLbl.centerX = self.addButton.centerX;
     83     addLbl.centerY = CGRectGetMaxY(self.addButton.frame) + 0.5 * AddButtonMargin + 0.5;
     84     
     85     [self addSubview:addLbl];
     86     
     87     self.addLabel = addLbl;
     88     
     89     int btnIndex = 0;
     90     //系统自带的按钮类型是UITabBarButton,找出这些类型的按钮,然后重新排布位置,空出中间的位置
     91     Class class = NSClassFromString(@"UITabBarButton");
     92     for (UIView *btn in self.subviews) {//遍历TabBar的子控件
     93         if ([btn isKindOfClass:class]) {//如果是系统的UITabBarButton,那么就调整子控件位置,空出中间位置
     94             //每一个按钮的宽度等于TabBar的三分之一
     95             btn.width = self.width / 3;
     96             
     97             btn.x = btn.width * btnIndex;
     98             
     99             btnIndex++;
    100             //如果索引是1(即“+”按钮),直接让索引加一
    101             if (btnIndex == 1) {
    102                 btnIndex++;
    103             }
    104             
    105         }
    106     }
    107     //将“+”按钮放到视图层次最前面
    108     [self bringSubviewToFront:self.addButton];
    109 }
    110 
    111 //重写hitTest方法,去监听"+"按钮和“添加”标签的点击,目的是为了让凸出的部分点击也有反应
    112 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    113     
    114     //这一个判断是关键,不判断的话push到其他页面,点击“+”按钮的位置也是会有反应的,这样就不好了
    115     //self.isHidden == NO 说明当前页面是有TabBar的,那么肯定是在根控制器页面
    116     //在根控制器页面,那么我们就需要判断手指点击的位置是否在“+”按钮或“添加”标签上
    117     //是的话让“+”按钮自己处理点击事件,不是的话让系统去处理点击事件就可以了
    118     if (self.isHidden == NO)
    119     {
    120         
    121         //将当前TabBar的触摸点转换坐标系,转换到“+”按钮的身上,生成一个新的点
    122         CGPoint newA = [self convertPoint:point toView:self.addButton];
    123         //将当前TabBar的触摸点转换坐标系,转换到“添加”标签的身上,生成一个新的点
    124         CGPoint newL = [self convertPoint:point toView:self.addLabel];
    125         
    126         //判断如果这个新的点是在“+”按钮身上,那么处理点击事件最合适的view就是“+”按钮
    127         if ( [self.addButton pointInside:newA withEvent:event])
    128         {
    129             return self.addButton;
    130         }
    131         //判断如果这个新的点是在“添加”标签身上,那么也让“+”按钮处理事件
    132         else if([self.addLabel pointInside:newL withEvent:event])
    133         {
    134             return self.addButton;
    135         }
    136         else
    137         {//如果点不在“+”按钮身上,直接让系统处理就可以了
    138             
    139             return [super hitTest:point withEvent:event];
    140         }
    141     }
    142     else
    143     {
    144         //TabBar隐藏了,那么说明已经push到其他的页面了,这个时候还是让系统去判断最合适的view处理就好了
    145         return [super hitTest:point withEvent:event];
    146     }
    147 }
    148 
    149 @end

    自定义TabBarController

    MyTabBarController.h

    1 #import <UIKit/UIKit.h>
    2 
    3 @interface MyTabBarController : UITabBarController
    4 
    5 @end

    MyTabBarController.m

     1 #import "MyTabBarController.h"
     2 #import "MyTabBar.h"
     3 
     4 
     5 @interface MyTabBarController () <MyTabBarDelegate> //实现自定义TabBar协议
     6 
     7 @end
     8 
     9 @implementation MyTabBarController
    10 
    11 - (void)viewDidLoad {
    12     [super viewDidLoad];
    13     // Do any additional setup after loading the view.
    14     
    15     //设置TabBar上第一个Item(明细)选中时的图片
    16     UIImage *listActive = [UIImage imageNamed:@"ListIcon - Active(blue)"];
    17     UITabBarItem *listItem = self.tabBar.items[0];
    18     //始终按照原图片渲染
    19     listItem.selectedImage = [listActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    20     
    21     
    22     //设置TabBar上第二个Item(报表)选中时的图片
    23     UIImage *chartActive = [UIImage imageNamed:@"ChartIcon - Active(blue)"];
    24     UITabBarItem *chartItem = self.tabBar.items[1];
    25     //始终按照原图片渲染
    26     chartItem.selectedImage = [chartActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    27     
    28     //创建自定义TabBar
    29     MyTabBar *myTabBar = [[MyTabBar alloc] init];
    30     myTabBar.myTabBarDelegate = self;
    31     
    32     //利用KVC替换默认的TabBar
    33     [self setValue:myTabBar forKey:@"tabBar"];
    34 }
    35 
    36 
    37 -(void)viewDidLayoutSubviews
    38 {
    39     [super viewDidLayoutSubviews];
    40     //设置TabBar的TintColor
    41     self.tabBar.tintColor = [UIColor colorWithRed:89/255.0 green:217/255.0 blue:247/255.0 alpha:1.0];
    42 }
    43 
    44 - (void)didReceiveMemoryWarning {
    45     [super didReceiveMemoryWarning];
    46     // Dispose of any resources that can be recreated.
    47 }
    48 
    49 
    50 
    51 #pragma mark - MyTabBarDelegate
    52 -(void)addButtonClick:(MyTabBar *)tabBar
    53 {
    54     //测试中间“+”按钮是否可以点击并处理事件
    55     UIAlertController *controller = [UIAlertController alertControllerWithTitle:@"test" message:@"Test" preferredStyle:UIAlertControllerStyleAlert];
    56     UIAlertAction *action = [UIAlertAction actionWithTitle:@"test" style:UIAlertActionStyleDefault handler:nil];
    57     [controller addAction:action];
    58     [self presentViewController:controller animated:YES completion:nil];
    59     
    60 }
    61 
    62 @end
  • 相关阅读:
    .NET Framework类库大概
    CTS、CLS、CIL与CLR
    .NETFramework、CLR、.NET Framework class library、托管代码是什么
    万维网三大核心技术
    Clang、GCC和LLVM是什么
    常见开源许可证、开源协议GPL、BSD、MIT、Mozilla、Apache和LGPL之间区别
    编译原理之变量、名字与标识符
    编译原理之静态策略与动态策略
    Jupyter Notebook打开任意文件
    修改VsCodes的语言为中文
  • 原文地址:https://www.cnblogs.com/guitarandcode/p/5759208.html
Copyright © 2011-2022 走看看