自定义和隐藏(自定义TabBar)

一. 自定义TabBar

1. 自定义概念:在长时间开发APP当中,我得出了一个结论,大多数系统的控件是无法满足我们的需求,此时我们就需要自己自定义控件.
2. 自定义控件需要达到的效果图

自定义tabBar成型图

3. 自定义继承UIView的XFTabBar

创建文件

4. 当view加载完毕的时候调用
- (void)viewDidLoad {
    [super viewDidLoad];

    //因为系统的tabBar不能满足尺寸的需求,所以这里我们自定义一个
    XFTabBar *tabBar = [[XFTabBar alloc] init];

    //如果要让底部的tabBar隐藏,那么就必须将自定义的tabBar尺寸设置为bounds,和系统的一样.
    tabBar.frame = self.tabBar.bounds;

    //通过一个get方法和一个set方法达到添加底部按钮的操作
    tabBar.arrayItem = self.arrayItem;

    //设置代理
    tabBar.delegate = self;
    //将系统的tabBar移除
    //只有将自定义的tabBar加在系统的tabBar上面,才能达到隐藏的效果
    [self.tabBar addSubview:tabBar];

二. 布局tabBar中的子控件

1. 通过下面代码作为桥梁
1.1 代码块一:
//tabBarItem本身就是一个模型,这里我们将每个控制器对应的tabBar存入可变数组中
    [self.arrayItem addObject:vc.tabBarItem];
1.2 代码块二:
#pragma mark - 懒加载

- (NSMutableArray *)arrayItem
{
    if (_arrayItem == nil) {
        _arrayItem = [NSMutableArray array];
    }
    return _arrayItem;
}
1.3 代码块三:
 //通过一个get方法和一个set方法达到添加底部按钮的操作
    tabBar.arrayItem = self.arrayItem;
2. 创建tabBar中的按钮(5个)
#pragma mark - 在里面创建tabBar下面的按钮
//重写arrayItemset方法-->在里面创建UIButton
- (void)setArrayItem:(NSArray *)arrayItem
{
    _arrayItem = arrayItem;

    for (int i = 0; i < arrayItem.count; i++) {
        //创建按钮
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];

        btn.tag = i;
        //根据传入的模型角标取出模型
        UITabBarItem *item = arrayItem[i];
        //设置按钮的背景图片
        [btn setBackgroundImage:item.image forState:UIControlStateNormal];
        [btn setBackgroundImage:item.selectedImage forState:UIControlStateSelected];

        //将创建出来的按钮添加到自定义的tabBar中
        [self addSubview:btn];

        //监听按钮的点击
        //UIControlEventTouchDown:由于是事件的点击,所以用这个
        [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
        //让程序已加载完,显示页面的时候,默认是在第0个按钮
        if (i == 0) {
            [self btnClick:btn];
        }
    }

}
3. 对按钮进行布局
3.1 布局思路:通过间每个按钮的宽度,然后在循环的时候,是第几个按钮,就乘以宽度.
#pragma mark - 布局子控件

- (void)layoutSubviews
{
    [super layoutSubviews];
    //重tabBar中取出每个子控件,告诉编译器是整数
    int count = (int)self.subviews.count;

    //计算每个子控件的位置
    CGFloat x = 0;
    CGFloat y = 0;
    //每个按钮的宽度
    CGFloat btnW = self.bounds.size.width / count;
    //每个按钮的高度
    CGFloat btnH = self.bounds.size.height;

    for (int i = 0; i < count; i++) {
        //是第几个按钮,就计算出对应的宽度
        x = i * btnW;
        //根据角标一次取出每个按钮
        UIButton *btn = self.subviews[i];
        btn.frame = CGRectMake(x, y, btnW, btnH);

    }
}
4. 对2中的按钮的监听方法实现
#pragma mark - 实现监听方法

- (void)btnClick:(UIButton *)btn
{
    //让上一个按钮取消选中状态
    self.preSelecBtn.selected = NO;

    //让当前的按钮选中
    btn.selected = YES;

    //让当前点击的按钮成为上一个选中的按钮
    self.preSelecBtn = btn;

    //调用代理
    //判断代理是否实现对应的代理方法
    if ([self.delegate respondsToSelector:@selector(tabBar:selectBtnIndex:)]) {
        //调用代理方法
        [self.delegate tabBar:self selectBtnIndex:btn.tag];   
    }  
}
5. 代理
5.1 用代理的原因:由于用户点击tabBar中的按钮,需要切换相对应的控制器,那么需要通过代理去寻找相对应的控制器
5.2 思路:
/*由于我们希望XFTabBarController控制器能知道用户点击的是哪个按钮,然后让控制器切换到对应的界面
 问题:但是怎么知道用户点击的是哪个按钮呢?
 实现方法:代理
 具体做法:在自定义的XFTabBar中设置代理属性,并且设置协议方法,通过协议中的方法将用户点击的是哪个按钮通过方法传递给控制器,然后控制器再切换到相应的界面
 代理人:XFTabBarController,让它实现协议的相应的方法,然后就能知道用户点击的是哪个按钮,做出相应的界面切换
 */
5.3 由于是对自定义的tabBar的代理,那么就需要协议,下面代码是在XFTabBar.h文件中的协议方法
@class XFTabBar;
@protocol XFTabBarDelegate<NSObject>

//协议的方法;selectBtnIndex传入相应的点击的角标
- (void)tabBar:(XFTabBar *)tabBar selectBtnIndex:(NSInteger)index;

@end

@interface XFTabBar : UIView

//创建数组
@property (nonatomic, strong) NSArray *arrayItem;

//设置代理
@property (nonatomic, weak) id<XFTabBarDelegate>delegate;
5.4 在view加载完毕的方法中已经设置了代理人
5.4 实现代理方法:将按钮的角标作为参数传入到协议方法中
#pragma mark - 实现代理方法

- (void)tabBar:(XFTabBar *)tabBar selectBtnIndex:(NSInteger)index
{
    //设置寻找第几个控制器
    self.selectedIndex = index; 
}

三. 隐藏自定义的tabBar

1. 当用户在指定的控制器中,点击其它跳转控制器的按钮的时候,会将自定义的tabBar隐藏,这样的设计给用户的体验比较好,毕竟一款好的APP看它是否成功,首先就要知道用户对这款APP的体验如何.用户体验好,那么这款APP就开发的有价值.
2.隐藏思路:
2.1 首先要设置自定义tabBar的尺寸,要和系统的一样
//如果要让底部的tabBar隐藏,那么就必须将自定义的tabBar尺寸设置为bounds,和系统的一样.
    tabBar.frame = self.tabBar.bounds;
2.2 将自定义的tabBar加入到系统的tabBar中
 [self.tabBar addSubview:tabBar];
2.3 遍历系统的tabBar中所有的子控件(在view即将显示的方法里面遍历和移除)
2.4 删除不属于自定义的控件(按钮)
#pragma mark - 当点击cell进入下一个页面的时候隐藏下面的tabBar
//在view即将显示的时候的方法里写
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    //遍历系统tabBar的所有子控件
    for (UIView *view in self.tabBar.subviews) {
        if (![view isKindOfClass:[XFTabBar class]]) {
        //移除不属于XFTabBar的子控件
            [view removeFromSuperview];
        }
    }
}
2.5 打印系统的tabBar所有子控件,我们不难看出:

遍历系统中的所有子控件

2.6 移除系统UITabBarButton原因:如果不将系统的按钮移除,那么就会遮住自定义的按钮.
3. 怎么在使得全局的非根控制器都能隐藏呢?
3.1 由于我们是用主流框架搭建的主框架:UITabBarController控制器 —>UINavigationController导航控制器,然后所有的子控制器都加在导航控制器中.
3.2 主流原因:只有以导航控制器为根控制器,才能设置每个只控制器的导航条内容.
3.3 在导航控制器中设置下面的代码就可以让全局的非根控制器隐藏
viewController.hidesBottomBarWhenPushed = YES;

四. 以上就是自定义tabBar和隐藏非根控制器的tabBar思路和源代码.大家还有什么更好的思路,给我留言,一起交流,谢谢!!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值