UITabBarController是用来管理视图控制器的, 如UINavigationController, UIViewController,与导航控制器不同,Tab控制器是用数组管理子视图控制器,并且子视图之间是平等关系。
在大部分的iOS应用中都有这样的一个用户界面:
这是iphone6模拟器中自带的图片浏览应用,它就是一个UITabBarController,点击底部的tabbar可以切换到不同的界面。
上图中的tabbar都是系统自带的,系统自带的tabbar的使用这里就不再赘述。
我们的目的是将底部的tabbar换成自己的图片,并且同样可以实现界面的切换。
最终的效果如下:
上图中的图片和文字是在一个图中的,并不是添加的文字。
首先, 创建工程并创建需要用到的类,这里用到5个uiviewcontroller
在AppDelegate中将uitabbarcontroller作为根视图;
在TabBarController中初始化属性;
创建5个视图:
- (void)_initViewControllers
{
OneViewController *oneCol = [[OneViewController alloc] init];
TwoViewController *twoCol = [[TwoViewController alloc] init];
ThreeViewController *threeCol = [[ThreeViewController alloc] init];
FourViewController *fourCol = [[FourViewController alloc] init];
FiveViewController *fiveCol = [[FiveViewController alloc] init];
// 需要将控制器保存到数组中,才能交给tabBar控制器管理
NSArray *colArray = @[oneCol, twoCol, threeCol, fourCol, fiveCol];
NSMutableArray *navColArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 5; i++) {
NavigationController *navCol = [[NavigationController alloc] initWithRootViewController:colArray[i]];
[navColArray addObject:navCol];
}
// 把五个导航控制器交给tabBar控制器去管理
self.viewControllers = navColArray;
}
- (void)_initViewControllers
{
OneViewController *oneCol = [[OneViewController alloc] init];
TwoViewController *twoCol = [[TwoViewController alloc] init];
ThreeViewController *threeCol = [[ThreeViewController alloc] init];
FourViewController *fourCol = [[FourViewController alloc] init];
FiveViewController *fiveCol = [[FiveViewController alloc] init];
// 需要将控制器保存到数组中,才能交给tabBar控制器管理
NSArray *colArray = @[oneCol, twoCol, threeCol, fourCol, fiveCol];
NSMutableArray *navColArray = [[NSMutableArray alloc] init];
for (int i = 0; i < 5; i++) {
NavigationController *navCol = [[NavigationController alloc] initWithRootViewController:colArray[i]];
[navColArray addObject:navCol];
}
// 把五个导航控制器交给tabBar控制器去管理
self.viewControllers = navColArray;
}
添加图片:
- (void)_initTabBarItems
{
// 设置tabBar的背景
[self.tabBar setBackgroundImage:[UIImage imageNamed:@"navbg"]];
//[self.tabBar setBackgroundColor:[UIColor greenColor]];
CGFloat itemWidth = [UIScreen mainScreen].bounds.size.width / 5;
// 获取tabBar的高度
CGFloat itemHeight = CGRectGetHeight(self.tabBar.frame);
// 添加选中滑块 UIImageView
_selectView = [[UIImageView alloc] initWithFrame:CGRectMake((itemWidth - 50) / 2, 3, 50,45)];
_selectView.image = [UIImage imageNamed:@"选中"];
[self.tabBar addSubview:_selectView];
//添加图标
for (int i = 0; i < 5; i++) {
UIButton *itemButton = [UIButton buttonWithType:UIButtonTypeCustom];
itemButton.frame = CGRectMake(i * itemWidth, 0, itemWidth, itemHeight);
itemButton.tag = i + 10;
NSString *imageName = [NSString stringWithFormat:@"%d.png",i + 1];
[itemButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
[itemButton addTarget:self action:@selector(itemAction:) forControlEvents:UIControlEventTouchUpInside];
[self.tabBar addSubview:itemButton];
}
}
- (void)_initTabBarItems
{
// 设置tabBar的背景
[self.tabBar setBackgroundImage:[UIImage imageNamed:@"navbg"]];
//[self.tabBar setBackgroundColor:[UIColor greenColor]];
CGFloat itemWidth = [UIScreen mainScreen].bounds.size.width / 5;
// 获取tabBar的高度
CGFloat itemHeight = CGRectGetHeight(self.tabBar.frame);
// 添加选中滑块 UIImageView
_selectView = [[UIImageView alloc] initWithFrame:CGRectMake((itemWidth - 50) / 2, 3, 50,45)];
_selectView.image = [UIImage imageNamed:@"选中"];
[self.tabBar addSubview:_selectView];
//添加图标
for (int i = 0; i < 5; i++) {
UIButton *itemButton = [UIButton buttonWithType:UIButtonTypeCustom];
itemButton.frame = CGRectMake(i * itemWidth, 0, itemWidth, itemHeight);
itemButton.tag = i + 10;
NSString *imageName = [NSString stringWithFormat:@"%d.png",i + 1];
[itemButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
[itemButton addTarget:self action:@selector(itemAction:) forControlEvents:UIControlEventTouchUpInside];
[self.tabBar addSubview:itemButton];
}
}
- (void)itemAction:(UIButton *)button
{
// 指定当前选中的控制器的位置 selectedIndex
self.selectedIndex = button.tag - 10;
[UIView animateWithDuration:0.3 animations:^{
_selectView.center = button.center;
}];
}
- (void)itemAction:(UIButton *)button
{
// 指定当前选中的控制器的位置 selectedIndex
self.selectedIndex = button.tag - 10;
[UIView animateWithDuration:0.3 animations:^{
_selectView.center = button.center;
}];
}
接下来就是将创建uitabbarcontroller时系统自带的tabbar移除。创建了5个,就有5个tabbar。
这几个tabbar时看不到的,但确实存在。如果不添加图片,在相应位置点击,同样可以跳转。
可以将添加图片那步注释,运行,尝试一下。
可以通过一下代码获得相关信息:
- (void)removeItems
{
NSArray *subViews = self.tabBar.subviews;
for (UIView *view in subViews) {
NSLog(@"view = %@",view);
}
}
- (void)removeItems
{
NSArray *subViews = self.tabBar.subviews;
for (UIView *view in subViews) {
NSLog(@"view = %@",view);
}
}
控制台会输出这样的信息:
2015-02-27 16:18:17.401 UITabBarController[3099:441686] view = <UITabBarButton: 0x7fcbd0e7bc10; frame = (2 1; 71 48); opaque = NO; layer = <CALayer: 0x7fcbd0e7c050>>
可以看到UITabBarButton就是tabbar所属的类;
将它移除
- (void)removeItems
{
NSArray *subViews = self.tabBar.subviews;
// NSClassFromString 将字符串转化为对象类型Class,因为自带的item为 UITabBarButton 类型没有公开不能直接拿到,所以需要转换
Class tabButtonclass = NSClassFromString(@"UITabBarButton");
// 指定移除 UITabBarButton 视图,其他的视图不移除
for (UIView *view in subViews) {
if ([view isKindOfClass:[tabButtonclass class]]) {
[view removeFromSuperview];
}
}
}
- (void)removeItems
{
NSArray *subViews = self.tabBar.subviews;
// NSClassFromString 将字符串转化为对象类型Class,因为自带的item为 UITabBarButton 类型没有公开不能直接拿到,所以需要转换
Class tabButtonclass = NSClassFromString(@"UITabBarButton");
// 指定移除 UITabBarButton 视图,其他的视图不移除
for (UIView *view in subViews) {
if ([view isKindOfClass:[tabButtonclass class]]) {
[view removeFromSuperview];
}
}
}
最后
- (void)viewDidLoad {
[super viewDidLoad];
[self _initViewControllers];
[self _initTabBarItems];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self _initViewControllers];
[self _initTabBarItems];
}
移除操作需要在viewDidAppear中调用:否则不能移除
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self removeItems];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self removeItems];
}
最后运行就能看到效果了;滑块会根据点击的图标滑动