源代码下载地址 https://github.com/xn4545945/XNTabbar
一、自定义的思路
iOS中的TabBarController确实已经很强大了,大部分主流iOS应用都会采用。但是往往也不能满足全部的需求,因此需要自定义TabBar,自定义需要对系统的TabBar工作方式有很好的理解,自定义需要勇气。
自定义TabBar的原则:尽量利用系统自带TabBar,只改需要改的地方。
三、细节很重要
#import
@interface XNTabBarController : UITabBarController
@end
XNTabBarController.m
//
// XNTabBarController.m
//
//
// Created by neng on 14-6-19.
// Copyright (c) 2014年 neng. All rights reserved.
//
#import "XNTabBarController.h"
#import "Common.h"
#import "XNTabBarButton.h"
@interface XNTabBarController ()
/**
* 设置之前选中的按钮
*/
@property (nonatomic, weak) UIButton *selectedBtn;
@end
@implementation XNTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
//下面两个方法在开发中是经常会用到的
// NSLog(@"%s",__func__);
// NSLog(@"%@",self.view.subviews); //能打印出所有子视图,和其frame
LogFun;
LogSubviews(self.view);
//删除现有的tabBar
CGRect rect = self.tabBar.frame;
[self.tabBar removeFromSuperview]; //移除TabBarController自带的下部的条
//测试添加自己的视图
UIView *myView = [[UIView alloc] init];
myView.frame = rect;
myView.backgroundColor = [UIColor redColor];
[self.view addSubview:myView];
for (int i = 0; i < 5; i++) {
//UIButton *btn = [[UIButton alloc] init];
XNTabBarButton *btn = [[XNTabBarButton alloc] init];
NSString *imageName = [NSString stringWithFormat:@"TabBar%d", i + 1];
NSString *imageNameSel = [NSString stringWithFormat:@"TabBar%dSel", i + 1];
[btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:imageNameSel] forState:UIControlStateSelected];
CGFloat x = i * myView.frame.size.width / 5;
btn.frame = CGRectMake(x, 0, myView.frame.size.width / 5, myView.frame.size.height);
[myView addSubview:btn];
btn.tag = i;//设置按钮的标记, 方便来索引当前的按钮,并跳转到相应的视图
//带参数的监听方法记得加"冒号"
[btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];
//设置刚进入时,第一个按钮为选中状态
if (0 == i) {
btn.selected = YES;
self.selectedBtn = btn; //设置该按钮为选中的按钮
}
}
}
/**
* 自定义TabBar的按钮点击事件
*/
- (void)clickBtn:(UIButton *)button {
//1.先将之前选中的按钮设置为未选中
self.selectedBtn.selected = NO;
//2.再将当前按钮设置为选中
button.selected = YES;
//3.最后把当前按钮赋值为之前选中的按钮
self.selectedBtn = button;
//4.跳转到相应的视图控制器. (通过selectIndex参数来设置选中了那个控制器)
self.selectedIndex = button.tag;
}
@end
XNTabBarButton.h
#import
@interface XNTabBarButton : UIButton
@end
XNTabBarButton.m
#import "XNTabBarButton.h"
@implementation XNTabBarButton
/**什么也不做就可以取消系统按钮的高亮状态*/
- (void)setHighlighted:(BOOL)highlighted{
// [super setHighlighted:highlighted];
}
@end
#import
@class XNTabBar;
@protocol XNTabBarDelegate
/**
* 工具栏按钮被选中, 记录从哪里跳转到哪里. (方便以后做相应特效)
*/
- (void) tabBar:(XNTabBar *)tabBar selectedFrom:(NSInteger) from to:(NSInteger)to;
@end
@interface XNTabBar : UIView
@property(nonatomic,weak) id delegate;
/**
* 使用特定图片来创建按钮, 这样做的好处就是可扩展性. 拿到别的项目里面去也能换图片直接用
*
* @param image 普通状态下的图片
* @param selectedImage 选中状态下的图片
*/
-(void)addButtonWithImage:(UIImage *)image selectedImage:(UIImage *) selectedImage;
@end
//
// XNTabBar.m
//
// Created by neng on 14-6-19.
// Copyright (c) 2014年 neng. All rights reserved.
//
#import "XNTabBar.h"
#import "XNTabBarButton.h"
@interface XNTabBar ()
/**
* 设置之前选中的按钮
*/
@property (nonatomic, weak) UIButton *selectedBtn;
@end
@implementation XNTabBar
/**
* 在这个方法里写控件初始化的东西, 调用init方法时会调用
*/
//- (id)initWithFrame:(CGRect)frame {
// if (self = [super initWithFrame:frame]) {
// //添加按钮
// for (int i = 0; i < 5; i++) { //取消掉特定的数字
// //UIButton *btn = [[UIButton alloc] init];
// XNTabBarButton *btn = [[XNTabBarButton alloc] init];
//
// NSString *imageName = [NSString stringWithFormat:@"TabBar%d", i + 1];
// NSString *imageNameSel = [NSString stringWithFormat:@"TabBar%dSel", i + 1];
//
// [btn setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
// [btn setImage:[UIImage imageNamed:imageNameSel] forState:UIControlStateSelected];
//
// [self addSubview:btn];
//
// btn.tag = i; //设置按钮的标记, 方便来索引当前的按钮,并跳转到相应的视图
//
// //带参数的监听方法记得加"冒号"
// [btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];
//
// if (0 == i) {
// [self clickBtn:btn];
// }
// }
// }
// return self;
//}
- (void)addButtonWithImage:(UIImage *)image selectedImage:(UIImage *)selectedImage {
UIButton *btn = [[UIButton alloc] init];
[btn setImage:image forState:UIControlStateNormal];
[btn setImage:selectedImage forState:UIControlStateSelected];
[self addSubview:btn];
//带参数的监听方法记得加"冒号"
[btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside];
//如果是第一个按钮, 则选中(按顺序一个个添加)
if (self.subviews.count == 1) {
[self clickBtn:btn];
}
}
/**专门用来布局子视图, 别忘了调用super方法*/
- (void)layoutSubviews {
[super layoutSubviews];
int count = self.subviews.count;
for (int i = 0; i < count; i++) {
//取得按钮
UIButton *btn = self.subviews[i];
btn.tag = i; //设置按钮的标记, 方便来索引当前的按钮,并跳转到相应的视图
CGFloat x = i * self.bounds.size.width / count;
CGFloat y = 0;
CGFloat width = self.bounds.size.width / count;
CGFloat height = self.bounds.size.height;
btn.frame = CGRectMake(x, y, width, height);
}
}
/**
* 自定义TabBar的按钮点击事件
*/
- (void)clickBtn:(UIButton *)button {
//1.先将之前选中的按钮设置为未选中
self.selectedBtn.selected = NO;
//2.再将当前按钮设置为选中
button.selected = YES;
//3.最后把当前按钮赋值为之前选中的按钮
self.selectedBtn = button;
//却换视图控制器的事情,应该交给controller来做
//最好这样写, 先判断该代理方法是否实现
if ([self.delegate respondsToSelector:@selector(tabBar:selectedFrom:to:)]) {
[self.delegate tabBar:self selectedFrom:self.selectedBtn.tag to:button.tag];
}
//4.跳转到相应的视图控制器. (通过selectIndex参数来设置选中了那个控制器)
//self.selectedIndex = button.tag;
}
@end
//
// XNTabBarController.m
//
// Created by neng on 14-6-19.
// Copyright (c) 2014年 neng. All rights reserved.
//
#import "XNTabBarController.h"
#import "XNTabBarButton.h"
#import "XNTabBar.h"
@interface XNTabBarController ()
/**
* 设置之前选中的按钮
*/
@property (nonatomic, weak) UIButton *selectedBtn;
@end
@implementation XNTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
//下面两个方法在开发中是经常会用到的
// NSLog(@"%s",__func__);
// NSLog(@"%@",self.view.subviews); //能打印出所有子视图,和其frame
// LogFun;
// LogSubviews(self.view);
//Hell
//删除现有的tabBar
CGRect rect = self.tabBar.bounds; //这里要用bounds来加, 否则会加到下面去.看不见
LogFrame(self.tabBar);
//[self.tabBar removeFromSuperview]; //移除TabBarController自带的下部的条
//测试添加自己的视图
XNTabBar *myView = [[XNTabBar alloc] init]; //设置代理必须改掉前面的类型,不能用UIView
myView.delegate = self; //设置代理
myView.frame = rect;
[self.tabBar addSubview:myView]; //添加到系统自带的tabBar上, 这样可以用的的事件方法. 而不必自己去写
//为控制器添加按钮
for (int i=0; i
例子源码下载 :https://github.com/xn4545945/XNTabbar (觉得还不错的可以给个star)
转载请注明出处:http://blog.csdn.net/xn4545945