美文网首页iOS移动开发社区
重修笔记之自定义UITabBarViewController

重修笔记之自定义UITabBarViewController

作者: iOS_July | 来源:发表于2018-03-26 16:21 被阅读34次
    tabBar0.gif
    在实际开发过程中,经常会发现系统自带的UITabBarViewController满足不了项目需求。
    这时候,就需要自定义一个满足需求的UITabBarViewController了。
    

    一、command + n

    • 想要自定义UITabBarViewController,需要先创建一个继承于系统UITabBarViewController的类文件。
    • 通常情况下,我们还需要自定义UITabBarViewController上的那个tabBar[往往是重点],继承于UIView即可。
    • 如:
    @interface JHTabBarViewController : UITabBarController
    
    @interface JHTabBar : UIView
    

    二、设置回调

    • 当我们点击某个tabBar时,需要用到回调来描述我们点击的究竟是什么,需要有什么样的效果。

    • 代理

    @class JHTabBar;//2
    //1、协议
    @protocol JHTabBarDelegate <NSObject>
    
    //3、协议方法
    - (void)tabBar:(JHTabBar *)tabBar clickBtn:(NSUInteger) index;
    @end
    
    @interface JHTabBar : UIView
    
    //4、设置代理
    @property(nonatomic, weak) id<JHTabBarDelegate> delegate;
    @end
    

    此时,只是用普通的index来代表我们的tabBar,为了使其更具意义,定义成枚举:

    //5、定义枚举
    typedef NS_ENUM(NSUInteger, JHItemType) {
        JHItemTypeMiddle,
        JHItemTypeLeft=100,//左边的item[具体意义自定]
        JHItemTypeRight
    };
    
    //再将index类型换为枚举类型
    - (void)tabBar:(JHTabBar *)tabBar clickBtn:(JHItemType) index;
    
    • block
      根据之前的分析可知,参数为JHTabBar类型的tabBar与JHItemType类型的index
    typedef void(^TabBlock)(JHTabBar * tabBar,JHItemType index);
    
    
    //7、block修饰使用copy
    @property (nonatomic, copy)TabBlock block;
    

    三、创建item

    先前我们已经定义好了代理和block,接下来设置item。

    • 先设置item的数据源
    /** item数据源 */
    @property (nonatomic, strong)NSArray * itemsList; 
    
    -(NSArray *)itemsList{
        if (!_itemsList) {
            _itemsList = @[@"tab_left",@"tab_right"];
        }
        return _itemsList;
    }
    
    • 有了item的数据源,就可以进行item的初始化了[itemsList里放的是tabBar未被选中时的图片名称]
    //view中、控件初始化
    -(instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if (self) {
            
            for (NSInteger i=0; i<self.itemsList.count; i++) {
                UIButton *item = [UIButton buttonWithType:UIButtonTypeCustom];
                [item setImage:[UIImage imageNamed:self.itemsList[i]] forState:UIControlStateNormal];
                [item setImage:[UIImage imageNamed:[self.itemsList[i] stringByAppendingString:@"_p"]] forState:UIControlStateSelected];
                [item addTarget:self action:@selector(clickItem:) forControlEvents:UIControlEventTouchUpInside];
                item.tag = JHItemTypeLeft + I;
               //图片取消高亮
                item.adjustsImageWhenHighlighted = NO;
                [self addSubview:item];
                
            }
        }
        return self;
    }
    
    • 计算frame
    -(void)layoutSubviews{
        [super layoutSubviews];
        
        CGFloat w = self.bounds.size.width / self.itemsList.count;
        
        for (NSInteger i=0; i< [self subviews].count; i++) {
            UIView * btn = [self subviews][I];
            if ([btn isKindOfClass:[UIButton class]]) {
                btn.frame = CGRectMake((btn.tag - JHItemTypeLeft)*w, 0, w, self.frame.size.height);
            }
        }
    }
    
    • 响应方法
    - (void)clickItem:(UIButton *)button{
        //判断代理是否能响应某个方法
        if ([self.delegate respondsToSelector:@selector(tabBar:clickBtn:)]) {
            [self.delegate tabBar:self clickBtn:button.tag];
        }
        
        //走block
        //!self.block?:self.block(self,button.tag)
        if (self.block) {
            self.block(self, button.tag);
        }
        
    }
    

    四、创建tabBar

    tanBar内部的定义先告一段落,现在在JHTabBarViewController里定义一个tabBar

    • 导入头文件
    #import "JHTabBar.h"
    
    • 创建自定义的tabBar
    @property (nonatomic, strong)JHTabBar * jhTabBar;
    
    • 设置代理
    @interface JHTabBarViewController ()<JHTabBarDelegate>
    
    • 懒加载
    -(JHTabBar *)jhTabBar{
        if (!_jhTabBar) {
            _jhTabBar = [[JHTabBar alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 49)];
            _jhTabBar.delegate = self;
        }
        return _jhTabBar;
    }
    
    • 加载控制器
    [self setupChildrenViewController];
    
    - (void)setupChildrenViewController{
        NSMutableArray * childArr = [NSMutableArray arrayWithArray:@[@"leftVC",@"rightVC"]];
        for (NSInteger i=0; i<childArr.count; i++) {
            NSString *vcName = childArr[I];
            
            UIViewController *vc = [[NSClassFromString(vcName) alloc]init];
            
            JHNavigationController * nav = [[JHNavigationController alloc]initWithRootViewController:vc];
            [childArr replaceObjectAtIndex:i withObject:nav];
            
        }
        self.viewControllers = childArr;
    }
    
    • 加载tabBar
    [self.tabBar addSubview:self.jhTabBar];
    
    • 实现代理方法
    #pragma mark ---- 实现JHTabBarDelegate方法
    -(void)tabBar:(JHTabBar *)tabBar clickBtn:(JHItemType)index{
        self.selectedIndex = index - JHItemTypeLeft;
    }
    

    五、添加lastItem

    • 在JHTabBar里
    /** 上一次点击的item */
    @property (nonatomic, strong) UIButton * lastItem;
    
    • - (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
    if (i==0) {
                    item.selected = YES;
                    self.lastItem = item;
                }
               
                [self addSubview:item];
    
    • 在响应事件- (void)clickItem:(UIButton *)button{}
    self.lastItem.selected = NO;
    button.selected = YES;
    self.lastItem = button;
    

    六、设置动画

    • 在响应事件- (void)clickItem:(UIButton *)button{}
    //设置动画
        [UIView animateWithDuration:0.2 animations:^{
            button.transform = CGAffineTransformMakeScale(1.2, 1.2);//先扩大到1.2
            
        }completion:^(BOOL finished) {
            [UIView animateWithDuration:0.2 animations:^{
                button.transform = CGAffineTransformIdentity;//恢复
            }];
        }];
    

    此时效果图:

    tabBar1.gif

    七、添加中间的特殊item

    • 在JHTabBar里
    /** 中间的特殊item */
    @property (nonatomic, strong) UIButton * midButton;
    
    • 懒加载
    -(UIButton *)midButton{
        if (!_midButton) {
            _midButton = [UIButton buttonWithType:UIButtonTypeCustom];
            [_midButton setImage:[UIImage imageNamed:@"tab_middle"] forState:UIControlStateNormal];
            _midButton.tag = JHItemTypeMiddle;
            [_midButton addTarget:self action:@selector(clickItem:) forControlEvents:UIControlEventTouchUpInside];
        }
        return _midButton;
    }
    
    • - (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;for循环之后
    //添加到视图
    [self addSubview:self.midButton];
    
    • -(void)layoutSubviews{}
    [self.midButton sizeToFit];
    self.midButton.center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height-40);
    
    • command+n创建特殊视图

    • 在JHTabBarViewController的代理方法里做修改

    #pragma mark ---- 实现JHTabBarDelegate方法
    -(void)tabBar:(JHTabBar *)tabBar clickBtn:(JHItemType)index{
        //不是特殊视图时
        if (index != JHItemTypeMiddle) {
            self.selectedIndex = index - JHItemTypeLeft;
            return;
        }
        
        //是模态视图
        middleVC * midVc = [[middleVC alloc]init];
        [self presentViewController:midVc animated:YES completion:nil];
           
    }
    

    此时效果图:

    tabBar2.gif
    ps:如想参照demo,可留言[按照之前的步骤,完全可以成功的]
    other:您也可以关注我的博客

    相关文章

      网友评论

        本文标题:重修笔记之自定义UITabBarViewController

        本文链接:https://www.haomeiwen.com/subject/tsilcftx.html