一. 自定义TabBar
1. 自定义概念:在长时间开发APP当中,我得出了一个结论,大多数系统的控件是无法满足我们的需求,此时我们就需要自己自定义控件.
2. 自定义控件需要达到的效果图
3. 自定义继承UIView的XFTabBar
4. 当view加载完毕的时候调用
- (void)viewDidLoad {
[super viewDidLoad];
XFTabBar *tabBar = [[XFTabBar alloc] init];
tabBar.frame = self.tabBar.bounds;
tabBar.arrayItem = self.arrayItem;
tabBar.delegate = self;
[self.tabBar addSubview:tabBar];
二. 布局tabBar中的子控件
1. 通过下面代码作为桥梁
1.1 代码块一:
[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下面的按钮
- (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];
[self addSubview:btn];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
if (i == 0) {
[self btnClick:btn];
}
}
}
3. 对按钮进行布局
3.1 布局思路:通过间每个按钮的宽度,然后在循环的时候,是第几个按钮,就乘以宽度.
#pragma mark - 布局子控件
- (void)layoutSubviews
{
[super layoutSubviews];
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 思路:
5.3 由于是对自定义的tabBar的代理,那么就需要协议,下面代码是在XFTabBar.h文件中的协议方法
@class XFTabBar;
@protocol XFTabBarDelegate<NSObject>
- (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
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
for (UIView *view in self.tabBar.subviews) {
if (![view isKindOfClass:[XFTabBar class]]) {
[view removeFromSuperview];
}
}
}
2.5 打印系统的tabBar所有子控件,我们不难看出:
3. 怎么在使得全局的非根控制器都能隐藏呢?
3.1 由于我们是用主流框架搭建的主框架:UITabBarController控制器 —>UINavigationController导航控制器,然后所有的子控制器都加在导航控制器中.
3.2 主流原因:只有以导航控制器为根控制器,才能设置每个只控制器的导航条内容.
3.3 在导航控制器中设置下面的代码就可以让全局的非根控制器隐藏
viewController.hidesBottomBarWhenPushed = YES;
四. 以上就是自定义tabBar和隐藏非根控制器的tabBar思路和源代码.大家还有什么更好的思路,给我留言,一起交流,谢谢!!!!