标签控制器(UITabBarController)常用于展示多个(并列的)视图,用户可以通过点击按钮快速地在多个视图控制器之间来回切换,使得程序的功能更为明确,对比导航控制器,它更多地用于控制多个没有层级关系的、频繁切换的视图。
UITabBarController 标签控制器是UIViewController的子类,它维护着一个控制器集合,可以快速的在多个控制器页面间切换。
UITableBarController标签控制器与UINavigationController不同的是,所有的被管理的控制器都是平级的。
标签控制器有两个层级:标签控制器视图、内容控制器视图。
UITableBarController以非栈的形式存储单元,而UINavigationController以栈的形式存储单元。
UITabBarController封装了一个UITabBar(标签栏)。
初始化:alloc + init
viewControllers:设置需要被管理的控制器集合
delegate:设置委托
selectedViewController:设置当前选中的控制器
selectedIndex:设置当前选中的控制器索引
tabBar:标签栏
任意一个视图控制器都可以切换到其他视图控制器,并且可以从任何其他视图控制器切换至它,所有视图控制器都可以通过标签控制器进行管理。
通过viewControllers属性可以获取到标签控制器所包含的所有控制器,通过selectedIndex属性以及selectedViewController属性可以获取到当前处于选中状态的控制器。
// 1、是否允许选中切换到某个视图控制器
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController;
// 2、选择了某个视图控制器
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController;
UITabBar中的元素由多个UITabBarItem构成;
UITabBarItem类似于UIBarButtonItem都是用于描述工具栏上每一个元素的显示以及对应的操作。
items:设置UITabBarItem集合
tintColor:设置标签栏主色调
barTintColor:设置标签栏背景色
selectedImageTintColor:设置UITabBarItem图片选中色
backgroundImage:设置标签栏背景图片
translucent:是否半透明
moreNavigationController:更多界面(当tabBarItem大于5个的时候会出现)
// 1、方法1:标题初始化(图片+tag)
- (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image tag:(NSInteger)tag;
// 2、方法2:标题初始化(图片+选中图片)
- (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image selectedImage:(UIImage *)selectedImage;
// 3、方法3:系统初始化
- (instancetype)initWithTabBarSystemItem:(UITabBarSystemItem)systemItem tag:(NSInteger)tag;
如果在标签控制器中需要导航栏,只需将标签控制器管理的视图控制器设为导航控制器即可。层级关系为:标签控制器 -> 导航控制器 -> 视图控制器
// 初始化根视图控制器
HomeViewController *homeVc = [[HomeViewController alloc] init];
MusicViewController *musicVc = [[MusicViewController alloc] init];
MessageViewController *messageVc = [[MessageViewController alloc] init];
SettingViewController *settingVc = [[SettingViewController alloc] init];
// 初始化导航控制器
UINavigationController *homeNav = [[UINavigationController alloc] initWithRootViewController:homeVc];
UINavigationController *musicNav = [[UINavigationController alloc] initWithRootViewController:musicVc];
UINavigationController *messageNav = [[UINavigationController alloc] initWithRootViewController:messageVc];
UINavigationController *settingNav = [[UINavigationController alloc] initWithRootViewController:settingVc];
// 初始化化标签控制器
UITabBarController *tabBarController = [[UITabBarController alloc] init];
// 设置标签控制器管理的视图控制器的集合
tabBarController.viewControllers = @[homeNav, musicNav, messageNav, settingNav];
// 设置更多控制器导航栏样式,注意:self为继承于UITabBarController的子类。
// 设置更多界面导航栏背景颜色
self.moreNavigationController.navigationBar.barTintColor = [UIColor blackColor];
// 设置更多界面导航栏前景色
self.moreNavigationController.navigationBar.tintColor = [UIColor whiteColor];
// 设置更多界面导航栏标题属性
self.moreNavigationController.navigationBar.titleTextAttributes = @{NSFontAttributeName : [UIFont boldSystemFontOfSize:20],NSForegroundColorAttributeName : [UIColor whiteColor]};
思路分析:要自定义标签栏其实很简单,首先需移除标签栏上的所有子视图,然后添加自定义视图即可。而要实现上述展示效果,我是通过三个按钮(UIButton)以及一个视图(UIView)来实现的,为按钮设置图片以及标题,并且调整它们的位置,然后在点击按钮的时候,将红色试图的中心点置为按钮的中心点即可,下面只贴上关键代码。
代码块1:
#import
@interface TabBarViewController : UITabBarController
@end
代码块2:
#pragma mark *** 自定义标签栏 ***
// 1、删除标签栏上所有的控件
for (UIView *subView in self.tabBar.subviews) {
[subView removeFromSuperview];
}
// 2、自定义item
// 创建数组存储自定义按钮图片的名字
NSArray *imageNames = @[kStringWithHomeTabBarItemImageName,kStringWithMessageTabBarItemImageName, kStringWithDynamicTabBarItemImageName];
CGFloat width = [UIScreen mainScreen].bounds.size.width/3;
CGFloat height = CGRectGetHeight(self.tabBar.bounds);
// 循环创建3个按钮(UIButton)替代UITabBarItem;
for (int i = 0; i < 3; i++) {
// 判断游标是否存在,如果不存在,则新建,通过if语句判断,可以避免游标视图被初始化多次。
if (!_filterView) {
_filterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
_filterView.backgroundColor = [UIColor redColor];
[self.tabBar addSubview:_filterView];
}
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
// 设置大小和位置
// i*width:平铺控件;
btn.frame = CGRectMake(i * width, 0, width, height);
// 设置标题
[btn setTitle:vcTitles[i] forState:UIControlStateNormal];
// 设置图片
[btn setImage:[UIImage imageNamed:imageNames[i]] forState:UIControlStateNormal];
// 设置标题与图片的偏移
btn.imageEdgeInsets = UIEdgeInsetsMake(-20, 0, 0, -30);
btn.titleEdgeInsets = UIEdgeInsetsMake(30, 0, 0, 37);
// 添加事件监听
[btn addTarget:self action:@selector(respondsToBtn:) forControlEvents:UIControlEventTouchUpInside];
// 设置tag值
btn.tag = BUTTON_TAG + i;
// 将按钮添加到标签栏上
[self.tabBar addSubview:btn];
}
代码块3:
#pragma mark *** Events methods ***
- (void)respondsToBtn:(UIButton *)sender {
// 根据触发方法按钮的下标设置当前选中的界面;
self.selectedIndex = sender.tag - BUTTON_TAG;
[UIView animateWithDuration:0.2 animations:^{
// 改变游标中心点
_filterView.center = sender.center;
}];
}