工作中,系统的TabBar往往无法满足我们的需求,下面就分享一下两种自定义TabBar的类型.
- 第一种tabBarItem为纯图片;
![Uploading 屏幕快照 2015-12-30 下午9.29.06_173366.png . . .]
- 第二种非主流型的,中间需要自定义的
针对第一种,系统的TabBar有一个image和tilte,如果使用系统的TabBar会显得非常难看
所以我们需要自定义TabBar
新建一个类继承UIView
.h文件
#import
@class XJTabBar;
@protocol XJTabBarDelegate
@optional
//tabBarItem的点击,将索引传出去
- (void)tabBar:(XJTabBar *)tabBar didClickbtn:(NSInteger)index;
@end
@interface XJTabBar : UIView
/** 子控件个数由外面的控制器决定 */
@property (nonatomic, strong) NSArray *items;
@property (nonatomic, weak) id delegate;
.m文件
@implementation XJTabBar
- (void)setItems:(NSArray *)items
{
_items = items;
for (int i = 0; i < items.count; i++) {
UITabBarItem *item = items[i];
XJTabBarBtn *btn = [[XJTabBarBtn alloc] init];
[btn setBackgroundImage:item.image forState:UIControlStateNormal];
[btn setBackgroundImage:item.selectedImage forState:UIControlStateSelected];
btn.tag = i;
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchDown];
if (i == 0) {
[self btnClick:btn];
}
[self addSubview:btn];
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat btnW = self.bounds.size.width / _items.count;
CGFloat btnH = self.bounds.size.height;
CGFloat btnX = 0;
CGFloat btnY = 0;
for (int i = 0; i < _items.count; i++) {
XJTabBarBtn *btn = self.subviews[i];
btnX = i * btnW;
btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
}
}
以上自定义TabBar就基本完成了,现在只需要在控制器中使用就OK了
自定义UITabBarController中
//初始化自定义tabBar
- (void)setuptabBar
{ //先将系统tabBar 移除
// [self.tabBar removeFromSuperview];
// 这里为什么我注销了呢? 因为是自定义的UITabBar,在push的时候,如果想要通过 `hidesBottomBarWhenPushed` 方法隐藏tabBar是无法实现的
XJTabBar *tabBar = [[XJTabBar alloc] init];
tabBar.frame = self.tabBar.bounds;
tabBar.items = self.tabBarArr;
tabBar.delegate = self;
[self.tabBar addSubview:tabBar];
}
现在基本上就是这个样子(下面的文字是由于我设置了控制器的title)
但是由于系统的UITabBarButton,尺寸还是显示不正确,所以需要将它删除掉,遍历tabbar的所有子控件,但是UITabBarButton是私有变量无法直接删除,如下,将不是自定义的XJTabBar的子控件删除
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
for (UIView *childView in self.tabBar.subviews) {
if ([childView isKindOfClass:[XJTabBar class]] == NO) {
[childView removeFromSuperview];
}
}
}
最后的结果(点击的时候按钮有高亮状态,自定义button,重写setHighlighted)
- (void)setHighlighted:(BOOL)highlighted
{
}
因为是自定义的UITabBar是继承UIView的,无法像系统的那样响应点击事件,切换控制器,所以需要实现代理方法
#pragma mark
- (void)tabBar:(XJTabBar *)tabBar didClickbtn:(NSInteger)index
{
//selectedindex是系统自带的属性,只要将按钮的索引传给它,就能实现点击切换控制器了
self.selectedIndex = index;
}
第二种UITabBar是百思不得姐的,中间的加号点击需要modal出一个控制器,所以系统的也无法满足我们的需求
实现思路和第一中有一点区别,这个我是直接继承系统的UITabBar,在上面做一些改变
.h文件
#import
@class XJTabBar;
@protocol XJTabBarDelegate
@optional
//加号按钮的点击
- (void)tabBarDidPulsBtnClick:(XJTabBar *)tabBar;
@end
@interface XJTabBar : UITabBar
/**代理 */
@property (nonatomic, weak) id delegate;
@end
.m文件
#import "XJTabBar.h"
@interface XJTabBar ()
/** 加号按钮 */
@property (nonatomic, weak) UIButton *pulsBtn;
@end
@implementation XJTabBar
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
//添加中间加号按钮
UIButton *pulsBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[pulsBtn setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
[pulsBtn setBackgroundImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
[pulsBtn sizeToFit];
self.pulsBtn = pulsBtn;
[self addSubview:pulsBtn];
[pulsBtn addTarget:self action:@selector(pulsBtnClick) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
- (void)layoutSubviews
{
[super layoutSubviews];
NSInteger count = self.items.count + 1;
CGFloat w = self.bounds.size.width / count;
CGFloat h = self.bounds.size.height;
CGFloat x = 0;
CGFloat y = 0;
int i = 0;
for(UIView *btn in self.subviews) {
if ([btn isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
if (i == 2) {
i += 1;
}
x = i * w;
btn.frame = CGRectMake(x, y, w, h);
i++;
}
//设置加号按钮尺寸
self.pulsBtn.center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
}
}
- (void)pulsBtnClick
{
if ([self.delegate respondsToSelector:@selector(tabBarDidPulsBtnClick:)]) {
[self.delegate tabBarDidPulsBtnClick:self];
}
}
@end
在自定义的UITabBarController中,将系统的UITabBar替换掉就OK了
- (void)viewDidLoad
{
[super viewDidLoad];
//@property(nonatomic,readonly) UITabBar *tabBar
//tabbar是readonly的,所以只能通过KVC赋值,不能直接更改
//为什么在这里更改系统的tabBar,在这里系统的tabBar还没有值
XJTabBar *tabBar = [[XJTabBar alloc] init];
tabBar.delegate = self;
[self setValue:tabBar forKeyPath:@"tabBar"];
}
最后实现加号对应的代理方法就行了,就能实现上图的效果了!
以上就是我对自定义tabBar的简单使用了,请多指教.......!
qq:1243157398