自定义TabBar01

首先说明一下为什么要自定义TabBar

默认TabBar有图片和文字,如果素材是图文分开的,那么一般不再需要自定义TabBar,如果素材是图文一起的,不设置文字,只设置了TabBar的图片,那么实现的效果就会片上方,留出文字的空白部分,如图:

TabBar.png

所以这种情况下一般需要自定义TabBar:

自定义TabBar.png

还有不同IOS下,TabBar的样式存在差别,如IOS6的拟物化,IOS7开始扁平化,如果需要支持多版本,同时达到样式一致,也可以通过自定义的方式实现(这种情况可能不会遇到,一般只要保证支持三个大版本就可以了)

先创建一个类,继承自UIView

@class JSTabBarView;

@protocol TabBarViewSelectedIndexDelegate 
//View中添加Button实现点击,此时还无法切换控制器,所以这里用到了代理,在创建Button的时候,设置Tag值,通过代理将Tag值回传,再通过TabBar控制器的selectedIndex属性切换控制器
- (void)tabBarView:(JSTabBarView *)tabBarView withSelectedJSButtonTag:(JSButton *)button;

@end

@interface JSTabBarView : UIView

@property (nonatomic,weak) id  delegate;
/**
 *  创建自定义TabBar中Button的图片
 *
 *  @param imageNormal UIControlStateNormal状态下的图片
 *  @param imageSel    UIControlStateSelected状态下的图片
 */
- (void)creatButtonWithNormalImage:(NSString *)normalImageName andSelectdImage:(NSString *)selectedImageName;

@end

.m文件中


@interface JSTabBarView ()
//JSButton继承自UIButton,里面只是重写了setHighlighted:(BOOL)highlighted,去掉系统默认提供的样式(点击button时高亮显示)
@property (nonatomic,strong) JSButton *selectedButton;
@end

@implementation JSTabBarView


- (void)creatButtonWithNormalImage:(NSString *)normalImageName andSelectdImage:(NSString *)selectedImageName{
    
    UIImage *normalImage = [UIImage imageNamed:normalImageName];
    UIImage *selectedImage = [UIImage imageNamed:selectedImageName];
    
    JSButton *button = [[JSButton alloc]init];
    
    [button setImage:normalImage forState:UIControlStateNormal];
    [button setImage:selectedImage forState:UIControlStateSelected];
    
    [self addSubview:button];
    
    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown];
    
}
 /**
  *   按钮的点击事件中主要有两部分:
  *   1.点中当前button时取消上一个button的选中状态
  *   2.代理对象执行代理方法
  */
- (void)buttonClick:(JSButton *)sender{
    
    self.selectedButton.selected = NO;
    
    sender.selected = YES;
    
    self.selectedButton = sender;
    
    
    if ( [self.delegate respondsToSelector:@selector(tabBarView:withSelectedJSButtonTag:)]) {
        
        [self.delegate tabBarView:self withSelectedJSButtonTag:sender];
        
    }
    
}

- (void)layoutSubviews{
    
    [super layoutSubviews];
    
    CGFloat width = self.bounds.size.width / self.subviews.count;
    CGFloat heigth = self.bounds.size.height;
    CGFloat buttonY = 0;
    
    for (int i = 0; i < self.subviews.count; i ++) {
        
        CGFloat buttonX = i * width;
        
        JSButton *button = (JSButton *)self.subviews[i];
        
        button.tag = i;
        
        button.frame = CGRectMake(buttonX, buttonY, width, heigth);
        
        if (i == 0) {
            
            [self buttonClick:button];
            
        }
        
        
    }
    
}

这样自定义的TabBar就可以导入使用了,先创建一个继承自TabBarController的类,创建一个自定义的TabBarView,并将TabBarView添加到当前自定义TabBarController的tabBar上,for循环创建自定义TabBar上的button,实现代理方法切换选中Button对应的控制器

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    /**
     *  获取导航控制器
     */
    UINavigationController *hallNavigationController = [self loadStoryBoardWithStoryBoardName:@"Hall"];
    UINavigationController *arenalNavigationController = [self loadStoryBoardWithStoryBoardName:@"Arenal"];
    UINavigationController *discoveryNavigationController = [self loadStoryBoardWithStoryBoardName:@"Discovery"];
    UINavigationController *historyNavigationController = [self loadStoryBoardWithStoryBoardName:@"History"];
    UINavigationController *myLotteryNavigationController = [self loadStoryBoardWithStoryBoardName:@"MyLottery"];
    
    //给当前的自定义TabBarController设置子控制器
    self.viewControllers = @[hallNavigationController,arenalNavigationController,discoveryNavigationController,historyNavigationController,myLotteryNavigationController];
    
    //创建自定义的TabBarView
    JSTabBarView *tabBarView = [[JSTabBarView alloc]init];
    
    //设置代理对象
    tabBarView.delegate = self;
    
//    tabBarView.frame = self.tabBar.frame;
//    [self.view addSubview:tabBarView];//如果按这种方式设置frame和添加到视图,当push到某一控制器后需要隐藏TabBar时,自定义的TabBarView还存在(所以需要通过设置bounds,并添加到tabBar上)

    //设置frame
    tabBarView.frame = self.tabBar.bounds;
    //将自定义的TabBarView添加到当前自定义TabBarController的tabBar上(将tabBar覆盖)
    [self.tabBar addSubview:tabBarView];
    
    //for循环创建自定义TabBarView中的button(根据子控制器的个数创建)
    for (int i = 0; i < self.viewControllers.count; i ++) {
        
        [tabBarView creatButtonWithNormalImage:[NSString stringWithFormat:@"TabBar%d",i+1] andSelectdImage:[NSString stringWithFormat:@"TabBar%dSel",i+1]];
        
    }
    
    
}

代理方法:

/**
 *  自定义TabBarView的代理方法,实现控制器切换
 *
 *  @param tabBarView 自定义的TabBarView
 *  @param button     选中的Button
 */
- (void)tabBarView:(JSTabBarView *)tabBarView withSelectedJSButtonTag:(JSButton *)button{
    //这里利用TabBarController的selectedIndex属性通过传递的button的tag值来进行设置,实现控制器的切换
    self.selectedIndex = button.tag;
    
}

你可能感兴趣的:(自定义TabBar01)