1.认识
1.UITabBarController和UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型的例子就是QQ、微信等应⽤。但是.前者其管理的视图一直存在,而后者在pop后会销毁掉,释放内存.
注意:UITabBarController通常作为整个程序的rootViewController,而且不能添加到别的container viewController中。2.它是如下所示的视图控制器,有人叫它分栏视图控制器,也有人叫它选项卡控制器或页签视图控制器(通常我不称它为标签视图控制器主要是为了避免和UILabel标签混淆),它是在很多App种都能见到的一种视图控制器,如下图所示
使用UITabBarController的场景很多,下图所示的微信和喜马拉雅听书都使用分栏视图控制器
2.使用分析
- 创建UITabBarController
// 创建分栏控制器
UITabBarController * tbc = [[UITabBarController alloc] init];
// 添加分栏控制器管理的视图控制器
tbc.viewControllers = @[视图控制器1, 视图控制器2, ... ];
// 将UITabBarController对象作为根视图控制器
self.window.rootViewController = tbc;
- UITabBarController的构成:
和UINavigationController非常类似,UITabBarController也包含一个UITabBar(选项卡栏),上面有若个个UITabBarItem(选项卡项),每个选项卡项又由标题、图片和徽章构成
- 将UINavigationController加入到UITabBarController中
UINavigationController和UITabBarController混合使用在App开发中还是很常见的,大致有两种使用模式:
1.UITabBarController各子界面是独立的导航关系,互不影响
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:@”FirstViewController” bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:@”SecondViewController” bundle:nil];
UINavigationController* nav1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
UINavigationController* nav2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
UITabBarController* tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:nav1, nav2, nil];
self.window.rootViewController = tabBarController;
2.应用整体是一个导航关系,只在根界面上分若干选项卡页
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:@”FirstViewController” bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:@”SecondViewController” bundle:nil];
UITabBarController* tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:tabBarController];
self.window.rootViewController = navController;
-
多于4个分栏的处理:
通常情况下分栏条最多支持5个视图控制器,如果超过5个,只显示4个,第5项变成了一个More,点击后会出现一个UITableViewController用于放置多余的视图控制器,通过导航可以切换,也可以对其进行编辑,如下图所示:
- 显示上次选中的视图:
NSUserDefaults提供了 standardUserDefaults 类方法来获得NSUserDefaults对象,接下来就是键值对映射的读写操作,使用起来非常的简单
// 实现UITabBarControllerDelegate协议中的方法在选中某个视图控制器时回调
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
NSUserDefaults *userDef = [NSUserDefaults standardUserDefaults];
// 将用户选中的视图控制器的索引通过NSUserDefaults对象存储起来
[userDef setInteger:tabBarController.selectedIndex forKey:@"selectedTabIndex"];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// ... ...
NSUserDefaults *userDef = [NSUserDefaults standardUserDefaults];
// 将UITabBarController对象选中的索引设置为plist存储的选中索引
tbc.selectedIndex = [userDef integerForKey:@"selectedTabIndex"];
// ... ...
}
- 获取UITabBarController中的所有子视图控制器:
viewControllers属性可以帮助我们获得分栏视图控制器上所有的子视图控制器的数组,我们可以通过下标运算来获得某个子视图控制器
-
UITabBar和UITabBarItem:
1.图片:selectedImage属性
2.徽章:badgeValue属性
3.颜色:tintColor属性
3.UITabBarController的定制
如何定制一个喜马拉雅听书那样的UITabBarController呢?我们可以继承UITabBarController并隐去自带的UITabBar,然后对整个下面的区域进行完全定制。XIB的可视化效果和关键代码如下所示:
#import "CDMyTabBarController.h"
@interface CDMyTabBarController () {
UIView *bottomView;
}
@end
@implementation CDMyTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
// 隐去原有的分栏条
self.tabBar.hidden = YES;
// 通过XIB加载一个视图替换原来的分栏条
bottomView = [[[NSBundle mainBundle] loadNibNamed:@"CDMyTabBarView" owner:self options:nil] firstObject];
CGRect rect = self.view.bounds;
bottomView.frame = CGRectMake(0, rect.size.height - 92, rect.size.width, 92);
[self.view addSubview:bottomView];
for (UIView *tempView in bottomView.subviews) {
if ([tempView isKindOfClass:[UIButton class]]) {
UIButton *tempButton = (id)tempView;
[tempButton addTarget:self action:@selector(tabBarButtonItemClicked:) forControlEvents:UIControlEventTouchUpInside];
}
}
}
- (void)tabBarButtonItemClicked:(UIButton *)sender {
// 根据按钮的tag值确定选中的分栏的索引
self.selectedIndex = sender.tag - 200;
// 将所有按钮的设置为未选中状态
for (UIView *tempView in bottomView.subviews) {
if ([tempView isKindOfClass:[UIButton class]]) {
UIButton *tempButton = (id)tempView;
tempButton.selected = NO;
}
}
// 将点击的按钮设置为选中状态
sender.selected = YES;
}
@end
相关链接:
http://www.jianshu.com/p/3dca06785c23
http://www.jianshu.com/p/bedf090f1416