关于tabBar这个控件,相信大家都不太陌生,基本上每个app都会用的到tab.但是,使用的情况却不一定,根据不同的需求,我们可能会遇到自定义tab的问题.
像我目前项目中就遇到了这种问题(以前用的storyboard,系统的tab),现在又该需求,增加中间自定义按钮.(面对这种需求,真心的希望大家不要遇到).
下面说一下tabBar自定义问题
1.tabBar自定义(一) - 完全自定义
这种方法首先要隐藏系统自带的tabbar,UIView设计成需求样式添加到tabController中(位置可以自定义),同事实现UIView中点击事件,对应原item的点击事件.(下面demo 简单描述了完全自定义的tabBar的方法,其他自己扩充)
#import "SHEEPTabBarController.h"
#import "Masonry.h"
/** 自定义TabBar的原理
* 1.隐藏掉系统自带的tabbar
* 2.使用自定义的视图,代替tabbar
* 3.选中按钮时,执行selectIndex的切换操作
*/
@interface SHEEPTabBarController ()
/** 自定义tabbar所在视图,全屏宽,距离上方20(让出电池条);高度 = 原声tabbar */
@property(nonatomic,strong)UIView *customTabBarView;
@end
@implementation SHEEPTabBarController
//懒加载
/** */
- (UIView *)customTabBarView {
if(_customTabBarView == nil) {
_customTabBarView = [[UIView alloc] init];
_customTabBarView.backgroundColor = [UIColor lightGrayColor];
[self.view addSubview:_customTabBarView];
//约束(Mansard)
[_customTabBarView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(0);
make.top.mas_equalTo(20);
make.height.mas_equalTo(self.tabBar.mas_height);
}];
NSArray *buttoncolors = @[[UIColor yellowColor],[UIColor brownColor],[UIColor whiteColor],[UIColor cyanColor]];
//指针指向上一个按钮
UIButton *lastButton = nil;
for (int i = 0; i< buttoncolors.count; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = buttoncolors[i];
[_customTabBarView addSubview:button];
[button mas_makeConstraints:^(MASConstraintMaker *make) {
//上下为0
make.top.bottom.mas_equalTo(0);
//等宽
if (i == 0) {
make.left.mas_equalTo(0);
}else
{
make.left.mas_equalTo(lastButton.mas_right).mas_equalTo(0);
make.width.mas_equalTo(lastButton);
if (i == buttoncolors.count - 1) {
make.right.mas_equalTo(0);
}
}
}];
lastButton = button;
//添加点击事件
[button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];
//通过按钮的tag值来区分当前是那个按钮出发的点击事件
button.tag = 100 + i;
}
}
return _customTabBarView;
}
- (void)viewDidLoad {
[super viewDidLoad];
//1.隐藏系统自带的tabbar
self.tabBar.hidden = YES;
//调用懒加载
self.customTabBarView.hidden = NO;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//customTabBar 点击事件
- (void)clickButton:(UIButton *)sender{
//100,101,102,103
NSInteger tag = sender.tag;
//控制器的索引值是0~3
self.selectedIndex = tag - 100;
}
@end
2.自定义tabBar的第二种方法 - 部分自定义
此种方式自定义tabBar的原理: 取出tabBar中的items,重新分配item的位置和大小,留出需要自定义的item位置;然后添加自定义部分的按钮.
然后,上代码吧
#import "CRTabBar.h"
@interface CRTabBar ()
@property (nonatomic, weak) UIButton *plusButton;
@end
@implementation CRTabBar
/**
* 用法 KVC
* tabController 加载时 :
* [self setValue: tabbar forKey:@"tabBar"];
*/
- (UIButton *)plusButton
{
if (_plusButton == nil) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@"tabbar_compose_background_icon_add"] forState:UIControlStateHighlighted];
[btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(touchAddButton) forControlEvents:UIControlEventTouchUpInside];
// 默认按钮的尺寸跟背景图片一样大
// sizeToFit:默认会根据按钮的背景图片或者image和文字计算出按钮的最合适的尺寸
[btn sizeToFit];
_plusButton = btn;
[self addSubview:_plusButton];
}
return _plusButton;
}
// self.items UITabBarItem模型,有多少个子控制器就有多少个UITabBarItem模型
// 调整子控件的位置
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat w = self.bounds.size.width;
CGFloat h = self.bounds.size.height;
CGFloat btnX = 0;
CGFloat btnY = 0;
CGFloat btnW = w / (self.items.count + 1);
CGFloat btnH = self.bounds.size.height;
int i = 0;
// 调整系统自带的tabBar上的按钮位置
for (UIView *tabBarButton in self.subviews) {
// 判断下是否是UITabBarButton
if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton" )]) {
if (i == 2) {
i = 3;
}
btnX = i * btnW;
tabBarButton.frame = CGRectMake(btnX, btnY, btnW, btnH);
i++;
}
}
// // 设置添加按钮的位置
self.plusButton.center = CGPointMake(w * 0.5, h * 0.5);
}
- (void)touchAddButton
{
NSLog(@"+++++++++++++++++");
}
最后一步!!!!!! : 在tabController中 :
CRTabBar *tabBar = [[CRTabBar alloc] initWithFrame:self.tabBar.frame];
// 利用KVC把readly的属性改
[self setValue:tabBar forKeyPath:@"tabBar"];
kvc 方式,改变原有的tabbar;
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
在重定义item位置的时候,大家可能会遇到一些问题,在系统语言版本不同的情况下,可能获取到的item位置会发生偏移.
例如:英文系统时: item位置调整后完全正常
中文或其他语言: item的位置会向前移动一个位置,此种情况,在调整位置时可以判断一下语言环境,再做更改:
// 调整子控件的位置
- (void)layoutSubviews
{
[super layoutSubviews];
CRLog(@"%@",[[NSLocale preferredLanguages]firstObject]);
CGFloat w = self.bounds.size.width;
//CGFloat h = self.bounds.size.height;
CGFloat btnX = 0;
CGFloat btnY = 0;
CGFloat btnW = w / (self.items.count + 1);
CGFloat btnH = self.bounds.size.height;
//判断语言环境
NSRange range = [[[NSLocale preferredLanguages]firstObject] rangeOfString:@"en"];
int i=0;
// 调整系统自带的tabBar上的按钮位置
if (range.length == 0) {
i = 1;
}
for (UIView *tabBarButton in self.subviews) {
// 判断下是否是UITabBarButton
if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton" )]) {
if (i == 2) {
i = 3;
}
btnX = i * btnW;
tabBarButton.frame = CGRectMake(btnX, btnY, btnW, btnH);
if (range.length == 0 && i==5) {
tabBarButton.frame = CGRectMake(0, btnY, btnW, btnH);
}
i++;
}
}
}
此种方式,将自定义位置留出,关于何时添加自定义按钮,可根据需求来设计;
就这么多了,菜鸟一枚,最近才转的ios,遇到的问题很多,希望可以和大家一起分享.如果有什么问题,希望大家可以提出来,谢谢大家.
与大家一起成长.