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

与大家一起成长.

推荐阅读更多精彩内容

  • 实现自定义分段控件 相关属性声明 封装初始化类方法。调用初始化方法传入参数:需要设定的整个控件的frame 以及 ...
    WeiHing阅读 6,170评论 0 8
  • iOS_autoLayout_Masonry 概述 Masonry是一个轻量级的布局框架与更好的包装AutoLay...
    指尖的跳动阅读 920评论 1 4
  • (一)Masonry介绍 Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布...
    杨梦鸽阅读 1,757评论 0 3
  • Masonry是一个轻量级的布局框架,拥有自己的描述语法,采用更优雅的链式语法封装自动布局,简洁明了并具有高可读性...
    3dcc6cf93bb5阅读 1,252评论 0 1
  • 原理:TabBar本身是一个View,自定义一个继承TabBar的uiview,然后替换掉原来的TabBar 下面...
    天涯笑笑生阅读 1,544评论 0 3
  • 今天说的这幅画,你一定在哪里见过。是啊,美的不要不要的。 这幅画挂在大名鼎鼎的佛罗伦萨乌菲兹美术馆里,接受着无数人...
    好奇心美术馆阅读 524评论 0 0
  • 暗夜的风, 带着温热的气息。 轻轻吹过, 撩乱缕缕青丝。 发梢的香, 轻轻飘入鼻尖。 触荡着心湖, 卷起朵朵涟漪。...
    花昼暖阅读 165评论 0 1
  • 不知从何时开始,“宫寒”一词闯入女人们的生活。 不管是小到月经不调、痛经,还是大到不孕不育,除了癌症,几乎所有妇科...
    沐晨雨rara阅读 837评论 0 0