标签:
一、自己定义的思路
iOS中的TabBarController确实已经非常强大了。大部分主流iOS应用都会採用。
可是往往也不能满足所有的需求,因此须要自己定义TabBar,自己定义须要对系统的TabBar工作方式有非常好的理解,自己定义须要勇气。
自己定义TabBar的原则:尽量利用系统自带TabBar,仅仅改须要改的地方。
三、细节非常重要
#import <UIKit/UIKit.h> @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 () /** * 设置之前选中的button */ @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;//设置button的标记, 方便来索引当前的button,并跳转到对应的视图 //带參数的监听方法记得加"冒号" [btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside]; //设置刚进入时,第一个button为选中状态 if (0 == i) { btn.selected = YES; self.selectedBtn = btn; //设置该button为选中的button } } } /** * 自己定义TabBar的button点击事件 */ - (void)clickBtn:(UIButton *)button { //1.先将之前选中的button设置为未选中 self.selectedBtn.selected = NO; //2.再将当前button设置为选中 button.selected = YES; //3.最后把当前button赋值为之前选中的button self.selectedBtn = button; //4.跳转到对应的视图控制器. (通过selectIndex參数来设置选中了那个控制器) self.selectedIndex = button.tag; } @end
XNTabBarButton.h
#import <UIKit/UIKit.h> @interface XNTabBarButton : UIButton @end
XNTabBarButton.m
#import "XNTabBarButton.h" @implementation XNTabBarButton /**什么也不做就能够取消系统button的高亮状态*/ - (void)setHighlighted:(BOOL)highlighted{ // [super setHighlighted:highlighted]; } @end
#import <UIKit/UIKit.h> @class XNTabBar; @protocol XNTabBarDelegate <NSObject> /** * 工具栏button被选中, 记录从哪里跳转到哪里. (方便以后做对应特效) */ - (void) tabBar:(XNTabBar *)tabBar selectedFrom:(NSInteger) from to:(NSInteger)to; @end @interface XNTabBar : UIView @property(nonatomic,weak) id<XNTabBarDelegate> delegate; /** * 使用特定图片来创建button, 这样做的优点就是可扩展性. 拿到别的项目里面去也能换图片直接用 * * @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 () /** * 设置之前选中的button */ @property (nonatomic, weak) UIButton *selectedBtn; @end @implementation XNTabBar /** * 在这种方法里写控件初始化的东西, 调用init方法时会调用 */ //- (id)initWithFrame:(CGRect)frame { // if (self = [super initWithFrame:frame]) { // //加入button // 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; //设置button的标记, 方便来索引当前的button,并跳转到对应的视图 // // //带參数的监听方法记得加"冒号" // [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]; //假设是第一个button, 则选中(按顺序一个个加入) 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++) { //取得button UIButton *btn = self.subviews[i]; btn.tag = i; //设置button的标记, 方便来索引当前的button,并跳转到对应的视图 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的button点击事件 */ - (void)clickBtn:(UIButton *)button { //1.先将之前选中的button设置为未选中 self.selectedBtn.selected = NO; //2.再将当前button设置为选中 button.selected = YES; //3.最后把当前button赋值为之前选中的button 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 () <XNTabBarDelegate> /** * 设置之前选中的button */ @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上, 这样能够用的的事件方法. 而不必自己去写 //为控制器加入button for (int i=0; i<self.viewControllers.count; i++) { //依据有多少个子视图控制器来进行加入button NSString *imageName = [NSString stringWithFormat:@"TabBar%d", i + 1]; NSString *imageNameSel = [NSString stringWithFormat:@"TabBar%dSel", i + 1]; UIImage *image = [UIImage imageNamed:imageName]; UIImage *imageSel = [UIImage imageNamed:imageNameSel]; [myView addButtonWithImage:image selectedImage:imageSel]; } // //加入button // 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;//设置button的标记, 方便来索引当前的button,并跳转到对应的视图 // // //带參数的监听方法记得加"冒号" // [btn addTarget:self action:@selector(clickBtn:) forControlEvents:UIControlEventTouchUpInside]; // // //设置刚进入时,第一个button为选中状态 // if (0 == i) { // btn.selected = YES; // self.selectedBtn = btn; //设置该button为选中的button // } // } } /**永远别忘记设置代理*/ - (void)tabBar:(XNTabBar *)tabBar selectedFrom:(NSInteger)from to:(NSInteger)to { self.selectedIndex = to; } /** * 自己定义TabBar的button点击事件 */ //- (void)clickBtn:(UIButton *)button { // //1.先将之前选中的button设置为未选中 // self.selectedBtn.selected = NO; // //2.再将当前button设置为选中 // button.selected = YES; // //3.最后把当前button赋值为之前选中的button // self.selectedBtn = button; // // //4.跳转到对应的视图控制器. (通过selectIndex參数来设置选中了那个控制器) // self.selectedIndex = button.tag; //} @end
样例源代码下载 : http://download.csdn.net/detail/xn4545945/7572263
转载请注明出处:http://blog.csdn.net/xn4545945
标签:
原文地址:http://www.cnblogs.com/gcczhongduan/p/5080574.html