1.UITabBar的基础结构与样式
A control that displays one or more buttons in a tab bar for selecting between different subtasks, views, or modes in an app.
如文档所说,每一个tabBar都会包含一个或者多个barItem,这些item用来执行任务,视图或者模块的切换。
因为一个tabbarController包含一个tabBar,同时tabBar中又包含了(N>0)个item,所以,自定义一个tabBar可以先从它的item做起。
2.创建一个barItem
以一个常规的item来说(不包含像QQ那样的可拖拽带动画的那种QAQ)通常都需要两张图片(选中,非选中)、一个相应的文字描述(字体颜色也应包括选中,非选中两种),下面开始以一个正常的item为例子,创建属于自己的item。
- (SM_TabBarItem *)initWithTitle:(NSString *)title image:(UIImage *)normalImage selectedImage:(UIImage *)selectedImage {
if (self = [super init]) {
self.normalImage = normalImage;
self.selectedImage = selectedImage;
_normalColor = [UIColor grayColor];
_highlightColor = [UIColor redColor];
self.title = title;
[self setupTitleLabel];
[self setupImageView];
screenWidth = [UIScreen mainScreen].bounds.size.width;
screenHeight = [UIScreen mainScreen].bounds.size.height;
}
return self;
}
- (void) setupTitleLabel {
_titleLabel = [[UILabel alloc] init];
_titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_titleLabel];
//Bottom
[NSLayoutConstraint constraintWithItem:_titleLabel attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0].active = YES;
//Left
[NSLayoutConstraint constraintWithItem:_titleLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:10].active = YES;
//Height
[NSLayoutConstraint constraintWithItem:_titleLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:16].active = YES;
//Width
[NSLayoutConstraint constraintWithItem:_titleLabel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:16*5].active = YES;
_titleLabel.text = self.title;
if (self.isSelected) {
_titleLabel.textColor = _highlightColor;
} else {
_titleLabel.textColor = _normalColor;
}
}
- (void) setupImageView {
_imageView = [[UIImageView alloc] init];
[self addSubview:_imageView];
_imageView.bounds = CGRectMake(0, 0, 25, 25);
_imageView.center = CGPointMake(self.frame.size.width/2, 19.5);
if (self.isSelected) {
_imageView.image = self.selectedImage;
} else {
_imageView.image = self.normalImage;
}
}
//卧槽,这特么一大段代码扔在这也太充数了吧(代码是今天下午找了点时间写的,没有做任何的优化,包括连控件的位置都没有调整,只是想法来了,写一个简版记录一下)
上面的代码使用了原生autolayout进行布局与相关约束工作,如果有这方面强的大神看到了这篇文章的话,我有个问题想请教,那个multiplier这个参数是干什么的呀。。。
这个类我暴露了两个属性值头文件中,分别是title属性和image属性。因为一个tabBarItem能够完整它的功能,是需要这两个属性来做支撑的。
创建tabBarView
同样的,我们一UIView作为父类,来创建一个子视图tabBarView。
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setupImageView];
[self setupTabBarItems];
}
return self;
}
- (void)setBackgroundImage:(UIImage *)backgroundImage {
_backgroundImageView.image = backgroundImage;
}
- (void) setupImageView {
_backgroundImageView = [[UIImageView alloc] init];
_backgroundImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_backgroundImageView];
//Top
[NSLayoutConstraint constraintWithItem:_backgroundImageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:100 constant:0].active = YES;
//Left
[NSLayoutConstraint constraintWithItem:_backgroundImageView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:0].active = YES;
//Bottom
[NSLayoutConstraint constraintWithItem:_backgroundImageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0].active = YES;
//Right
[NSLayoutConstraint constraintWithItem:_backgroundImageView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:0].active = YES;
}
- (void) setupTabBarItems {
UIImage *normalImage = [UIImage imageNamed:@"_normalImage"];
UIImage *selectedImage = [UIImage imageNamed:@"_selectedImage"];
_centerItem = [[SM_TabBarItem alloc] initWithTitle:@"TEST" image:normalImage selectedImage:selectedImage];
_centerItem.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_centerItem];
[NSLayoutConstraint constraintWithItem:_centerItem attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:_centerItem attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:_centerItem attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:_centerItem attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1 constant:0].active = YES;
}
其实我特别想做成Apple原生的那种,可以进行自动布局运算的那种tabBar,但是时间(zhishang)有限,暂时只能想出在tabBarView上提前将item进行装载并布局的方式。。。
因为我们要创建的是一个可以拥有自定义背景图的tabbar,所以,我在视图上面覆盖了一个imageView。
最后
其实也还没完,这篇文章我会持续去更新。如果想关心一下类似于QQ底部tabbar的实现,可以看一下iOS 模仿QQ侧滑菜单和UITabBar拖动动画这位大佬的文章。