iOS UITabBarController简单使用-创建、属性设置及组合使用UINavigationController

UITabBarController,在这个视图控制器中有一个UITabBar控件,用户通过点击tabBar进行视图切换。


我们知道在UIViewController内部有一个视图,一旦创建了UIViewController之后默认就会显示这个视图,但是UITabBarController本身并不会显示任何视图,如果要显示视图则必须设置其viewControllers属性(它默认显示viewControllers[0])。这个属性是一个数组,它维护了所有UITabBarController的子控制器。为了尽可能减少视图之间的耦合,所有的UITabBarController的子控制器的相关标题、图标等信息均由子控制器自己控制,UITabBarController仅仅作为一个容器存在。



这个工具条称为UITabBar ,如果UITabBarController有N个子控制器,那么UITabBar内部就会有N 个UITabBarItem作为子控件与之对应。

UITabBarItem⾥面显⽰什么内容,由对应子控制器的tabBarItem属性来决定

vc1.tabBarItem.title = @"首页";
vc1.tabBarItem.image = [[UIImage imageNamed:@"Home_normal"]  imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

1.使用storyboard混合代码创建、设置

看到网上很多代码都是使用纯代码创建UITabBarController组合使用UINavigationController的,不过个人觉得storyboard可以方便界面设计可视化,因为项目只有个人在负责,所以一开始使用的是这种混合的方法。
1)工程新建之后在storyboard中删掉ViewController,选择TabBarController拖到storyboard中,此时会看到一个TabBar Sense 对应两个初始场景Item1、Item2


TabBarController

记得要把TabBarController设置为初始视图控制器并绑定ViewController文件


设置为初始视图控制器

绑定ViewController文件

2)Delete删掉场景Item1、Item2。拖拽NavigationController控制器到storyboard。

连接TabBarController和NavigationController:从TabBarController按住鼠标右键拖动到NavigationController上,释放鼠标弹出Segue对话框,选择Relationship Segue中的view controllers。完成连接。
这只是完成了第一个标签的设计,其余标签如法炮制。

3)设置TabBar item 标签栏的文字、图标

  • 可以选中其中一个NavigationController的tabbar item,如图所示,设置item的内容,图片。但是这种设置方法都默认为系统的默认样式,如果需要对文字图片有特殊设置需求,需要使用代码进行设置。


    设置TabBar item 标签栏的文字、图标
  • 使用代码设置TabBar item 标签栏的文字、图标
    在TabBarController绑定的对应ViewController.m文件中:
    1.设置UITabBarItem字体颜色、大小(selected\normal状态下)

    改变UITabBarItem字体颜色、大小

    [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:102.0/255 green:102.0/255 blue:102.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateNormal];

    [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:255.0/255 green:73.0/255 blue:87.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont fontWithName:@"Helvetica" size:12.0f],NSFontAttributeName,nil] forState:UIControlStateSelected];

这是设置全局所有UITabBarItem字体的颜色、大小,如果要设置单个item字体的颜色大小(局部个性化,用当前tabbar item修改):

UITabBarItem *item0 = [self.tabBar.items objectAtIndex:0];
[item0 setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:102.0/255 green:102.0/255 blue:102.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateNormal];

这里要注意,设置字体的话要选择支持中文的字体,不然修改字号是无效的。

2.设置UITabBarItem文字内容、选中和非选中图片


文字内容、选中和非选中图片
  UITabBarItem *item0 = [self.tabBar.items objectAtIndex:0];
  //一开始这里使用[self.tabBarController.tabBar.items  objectAtIndex:0];出错,因为本身就是tabBarController其实直接获取tabBar就可以了
 //如果是在tabBarController的子控制器中通过self.tabBarController或者self.parentViewController,可以得到其父视图控制器,也就是tabBarController本身
  item0.image = [[UIImage imageNamed:@"Home_normal"]  imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  item0.selectedImage = [[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  item0.title = @"首页";
    
  UITabBarItem *item1 = [self.tabBar.items objectAtIndex:1];
  item1.image = [[UIImage imageNamed:@"Shopping_normal"]  imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  item1.selectedImage = [[UIImage imageNamed:@"Shopping_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
  item1.title = @"进货单";
  • 每个视图控制器都有一个tabBarController属性,通过它可以访问所在的UITabBarController,而且对于UITabBarController的直接子视图其tabBarController等于parentViewController。
  • 每个视图控制器都有一个tabBarItem属性,通过它控制视图在UITabBarController的tabBar中的显示信息。

iOS7中新增了方法:

 - (instancetype)initWithTitle:(nullableNSString *)title image:(nullableUIImage *)image selectedImage:(nullableUIImage *)selectedImage
 NS_AVAILABLE_IOS(7_0);`

上面的代码可以改为:

    item0  = [[UITabBarItem alloc] initWithTitle:@"首页"
                                           image:[[UIImage imageNamed:@"Home_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
                                   selectedImage:[[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
vc1.tabBarItem = item;//创建完标签之后指定为某一个视图控制器的标签

同时在相同的API中,有这么一个注释:

/* The unselected image is autogenerated from the image argument. The selected image is autogenerated from the selectedImage if provided and the image argument otherwise.To prevent system coloring, provide images with UIImageRenderingModeAlwaysOriginal (see UIImage.h) */
意思是为了防止系统渲染,必须以UIImageRenderingModeAlwaysOriginal提供图片。若不以这种形式,那么提供的图片显示时会发生渲染错误的问题。

UIImageRenderingMode属性

  • UIImageRenderingModeAutomatic // 根据图片的使用环境和所处的绘图上下文自动调整渲染模式。
  • UIImageRenderingModeAlwaysOriginal // 始终绘制图片原始状态,不使用Tint Color。
  • UIImageRenderingModeAlwaysTemplate // 始终根据Tint Color绘制图片,忽略图片的颜色信息。
    UIImageRenderingMode属性的默认值是UIImageRenderingModeAutomatic,UIBarButtonitem图标在这种情况下被渲染为蓝色而不是图标本身的颜色。设置为UIImageRenderingModeAlwaysOriginal才会保持图片原始状态。


3.设置UITabBarController“背景颜色”

  • 方法一
self.tabBar.barTintColor = [UIColor greenColor];

这里有一个要注意的是:在storyboard要勾掉TabBar 的Translucent,不然的话设置的背景颜色会有色差(navigation bar也有同样的问题存在)。



要勾掉Translucent

产生色差
  • 方法二
    除了使用代码,设置背景颜色也可以在上图红线下面的Bar Tint进行设置,同样要去掉Translucent
  • 方法三
[[UITabBar appearance]setBackgroundColor:[UIColor blueColor]];
[UITabBar appearance].translucent = NO;
  • 方法四
    在tabbar上添加一个有颜色的view
UIView *view = [[UIView alloc]init];
view.backgroundColor = [UIColor redColor];
view.frame = self.tabBar.bounds;
[[UITabBar appearance]insertSubview:view atIndex:0]
  • 方法五
    使用背景图片
[[UITabBar appearance]setBackgroundImage:[UIImage imageNamed:@"xxx"]];
[UITabBar appearance].translucent = NO;

关于barTintColor的一点扩展:如何在iOS 7中设置barTintColor实现类似网易和 Facebook 的 navigationBar 效果

所有的设置代码都是写在与UITabBarController绑定的ViewController.m文件里面,当然也可以在tabbar的各个子控制器中进行以上属性的设置。如果属性设置是写在子控制器的viewDidLoad里面的话,那么app加载之后就只有第一个页面的tabbar item的图标可以显示出来(因为其他页面还没有加载嘛..自然也就无法调用它们的viewdidload啦..),只有当切换到其他页面的时候,哪个页面的tabbar item的图标才会显示出来。

项目所有代码
#import <UIKit/UIKit.h>
@interface ViewController : UITabBarController

@end

#import "ViewController.h"
@interface ViewController ()

@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
//    NSArray *arr = [self childViewControllers];
//    UINavigationController *anav = [arr objectAtIndex:0];
//    UITabBarItem *item0 = [anav.tabBarController.tabBar.items objectAtIndex:0];
//    item0.image = [[UIImage imageNamed:@"Home_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
//    item0.selectedImage = [[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
//    item0.title = @"首页";
//    
//    UINavigationController *bnav = [arr objectAtIndex:1];
//    UITabBarItem *item1 = [bnav.tabBarController.tabBar.items objectAtIndex:1];
//    item1.image = [[UIImage imageNamed:@"Home_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
//    item1.selectedImage = [[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
//    item1.title = @"首页";
//    
//    UITabBarItem *item2 = [bnav.tabBarController.tabBar.items objectAtIndex:0];
//    item2.image = [[UIImage imageNamed:@"Shopping_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
//    item2.selectedImage = [[UIImage imageNamed:@"Shopping_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
//    item2.title = @"进货";
    [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:102.0/255 green:102.0/255 blue:102.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateNormal];
    [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:255.0/255 green:73.0/255 blue:87.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateSelected];
    
    UITabBarItem *item0 = [self.tabBar.items objectAtIndex:0];
    item0.image = [[UIImage imageNamed:@"Home_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    item0.selectedImage = [[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    item0.title = @"首页";
    
    UITabBarItem *item1 = [self.tabBar.items objectAtIndex:1];
    item1.image = [[UIImage imageNamed:@"Shopping_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    item1.selectedImage = [[UIImage imageNamed:@"Shopping_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    item1.title = @"进货单";

    item0  = [[UITabBarItem alloc] initWithTitle:@"首页"
                                           image:[[UIImage imageNamed:@"Home_normal"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
                                   selectedImage:[[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]];
//    self.tabBar.barTintColor = [UIColor blueColor];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

2.使用纯代码创建、设置

使用步骤:

  1. 初始化UITabBarController
  2. 设置UIWindow的rootViewController为UITabBarController
  3. 创建相应的子控制器(viewcontrollers)(子视图,新建自己需要的UIViewController或者UITableViewController等等,如果需要组合使用UINavigationController,可以将这些视图作为UINavigationController的根视图,使用initWithRootViewController:)
    http://www.jianshu.com/p/11a66e1a3b10
  4. 把子控制器添加到UITabBarController

在Application的中编码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    
    //初始化一个tabBar控制器
    UITabBarController *tb = [[UITabBarController alloc]init];
    //设置UIWindow的rootViewController为UITabBarController
    self.window.rootViewController = tb;
    
    //创建相应的子控制器
    UIViewController *vc1 = [[UIViewController alloc]init];
    vc1.view.backgroundColor = [UIColor greenColor];
    vc1.tabBarItem.title = @"首页";
    vc1.tabBarItem.image = [[UIImage imageNamed:@"Home_normal"]  imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    vc1.tabBarItem.selectedImage = [[UIImage imageNamed:@"Home_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    UIViewController *vc2 = [[UIViewController alloc]init];
    vc2.view.backgroundColor = [UIColor blueColor];
    vc2.tabBarItem.title = @"分类";
    vc2.tabBarItem.image = [[UIImage imageNamed:@"List_normal"]  imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    vc2.tabBarItem.selectedImage = [[UIImage imageNamed:@"List_selected"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:102.0/255 green:102.0/255 blue:102.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateNormal];
    
    [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor colorWithRed:255.0/255 green:73.0/255 blue:87.0/255 alpha:1.0],NSForegroundColorAttributeName, [UIFont systemFontOfSize:10.0],NSFontAttributeName,nil] forState:UIControlStateSelected];
    
    //把子控制器添加到UITabBarController
    //[tb addChildViewController:c1];
    //[tb addChildViewController:c2];
    //或者
    tb.viewControllers = @[vc1,vc2];
    [self.window makeKeyAndVisible];
    return YES;   
}

实现效果:



http://www.cnblogs.com/kenshincui/p/3940746.html 这里也有另一种创建方法可以参考,不过思路上都是相似的。

3.UITabBarController生命周期

http://www.cnblogs.com/wendingding/p/3775636.html 这里有一篇讲UITabBarController生命周期的博文。总结一下大概就是:

  1. 把子控制器都添加给TabBarController管理,当程序启动时它只会加载第一个添加的控制器的view
  2. 切换到第二个界面。先把第一个界面的view移开,再把新的view添加上去,但是第一个view只是被移开没有被销毁
  3. 重新切换到第一个界面,第一个的控制器直接viewWillAppear,没有执行viewDidLoad证明了2.中第一个view移除后并没有被销毁(因为它的控制器还存在,有一个强引用引用着它),且第二个界面的view移除后也没有被销毁。无论怎么切换,控制器和view都不会被销毁。
    UINavigationController和UITabBarController一个通过栈来管理,一个通过普通的数组来进行管理。

4.原生tabbar的隐藏

TabBar嵌套Nav时,主界面tabbar正常显示,进行Push的时候隐藏TabBar,pop回来又正常显示。

  • 设置hidesBottomBarWhenPushed属性为YES
    1.在vc1 push到下一个vc2时,在vc1中:
//使用storyboard用identifier获取Controller
    UITableViewController *v2 = [self.storyboard instantiateViewControllerWithIdentifier:@"v2"];
//或者 UITableViewController *v2 =[[UITableViewController alloc]init];
    v2.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:v2 animated:YES];

2.storyboard中拖线push,在prepareForSegue函数中:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
}

hidesBottomBarWhenPushed属性是对设置的该vc生效的(如果是对self设置就是本vc开始生效,对别的vc设置就是从该vc开始生效),并且会一直传递到后面的vc也生效。
不过如果往下第N级需要显示tabor,就不能用hidesBottomBarWhenPushed = NO;把他显示出来。不过可以用这种方法处理:单独处理每一级

//使用storyboard用identifier获取Controller
    UITableViewController *v2 = [self.storyboard instantiateViewControllerWithIdentifier:@"v2"];
//或者 UITableViewController *v2 =[[UITableViewController alloc]init];
    v2.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:v2 animated:YES];
    v2.hidesBottomBarWhenPushed = NO;
  • storyboard,在 ViewController 的设置面板中把 Hide Bottom Bar on Push 属性勾选上,从该vc开始生效


  • 使用self.tabBarController.tabBar.hidden = YES;不过会有个很怪异的现象。在storyboard里对tabbar的translucent属性取消勾选,push的时候底部会有黑边

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容