在实际开发过程中,经常会发现系统自带的UITabBarViewController满足不了项目需求。
这时候,就需要自定义一个满足需求的UITabBarViewController了。
一、command + n
- 想要自定义UITabBarViewController,需要先创建一个继承于系统UITabBarViewController的类文件。
- 通常情况下,我们还需要自定义UITabBarViewController上的那个tabBar
[往往是重点]
,继承于UIView即可。 - 如:
@interface JHTabBarViewController : UITabBarController
@interface JHTabBar : UIView
二、设置回调
当我们点击某个tabBar时,需要用到回调来描述我们点击的究竟是什么,需要有什么样的效果。
代理
@class JHTabBar;//2
//1、协议
@protocol JHTabBarDelegate
//3、协议方法
- (void)tabBar:(JHTabBar *)tabBar clickBtn:(NSUInteger) index;
@end
@interface JHTabBar : UIView
//4、设置代理
@property(nonatomic, weak) id 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
- 计算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 ()
- 懒加载
-(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
- 加载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;//恢复
}];
}];
此时效果图:
七、添加中间的特殊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];
}