关于自定义TabBar的记录

      关于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,遇到的问题很多,希望可以和大家一起分享.如果有什么问题,希望大家可以提出来,谢谢大家.

与大家一起成长.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 实现自定义分段控件 相关属性声明 封装初始化类方法。调用初始化方法传入参数:需要设定的整个控件的frame 以及 ...
    WeiHing阅读 6,629评论 0 8
  • iOS_autoLayout_Masonry 概述 Masonry是一个轻量级的布局框架与更好的包装AutoLay...
    指尖的跳动阅读 1,149评论 1 4
  • (一)Masonry介绍 Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布...
    木易林1阅读 2,312评论 0 3
  • Masonry是一个轻量级的布局框架,拥有自己的描述语法,采用更优雅的链式语法封装自动布局,简洁明了并具有高可读性...
    3dcc6cf93bb5阅读 1,751评论 0 1
  • 原理:TabBar本身是一个View,自定义一个继承TabBar的uiview,然后替换掉原来的TabBar 下面...
    天涯笑笑生阅读 1,864评论 0 3