自定义两种TabBar类型

工作中,系统的TabBar往往无法满足我们的需求,下面就分享一下两种自定义TabBar的类型.

  1. 第一种tabBarItem为纯图片;

![Uploading 屏幕快照 2015-12-30 下午9.29.06_173366.png . . .]


屏幕快照 2015-12-30 下午9.22.10.png
  1. 第二种非主流型的,中间需要自定义的
屏幕快照 2015-12-30 下午9.29.06.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)


屏幕快照 2015-12-30 下午9.20.19.png
但是由于系统的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
{
    
}
屏幕快照 2015-12-30 下午9.20.56.png

因为是自定义的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

你可能感兴趣的:(自定义两种TabBar类型)