UITabBarController的原理:
- UITabBarController会一次性初始化所有子控制器,但是默认只加载第一个控制器视图,其他视图控制器只初始化默认不会加载,为了能够将其他子控制器也正常显示在Tab bar中我们访问了每个子视图控制器的视图以便调用其视图加载方法(viewDidLoad);当然,既然会调用子视图的初始化方法,当然也可以将视图控制器的tabBarItem属性设置放到init方法中设置,如此则不用再遍历其视图属性了。
- 每个视图控制器都有一个tabBarController属性,通过它可以访问所在的UITabBarController,而且对于UITabBarController的直接子视图其tabBarController等于parentViewController。
- 每个视图控制器都有一个tabBarItem属性,通过它控制视图在UITabBarController的tabBar中的显示信息。
- tabBarItem的image属性必须是png格式(建议大小32*32)并且打开alpha通道否则无法正常显示。
导航控制器nav,nav的根控制器vc1; 下一个控制器leftVC;按钮在vc1 的导航上(场景:在vc1中点击按钮,push 到leftVC)
设置下一个控制器的tabBar隐藏,要在push之前设置(在按钮中设置)
vc1.hidesBottomBarWhenPushed=YES;//push到下一个控制器会隐藏tabBar;
[vc1.navigationControllerpushViewController:leftVCanimated:YES]//push到leftVC控制器
vc1.hidesBottomBarWhenPushed=NO;//回到上一个控制器不隐藏tabBar;
==================================
场景:在根控制器view Did Load中,点击按钮之前设置隐藏,会启动程序就隐藏
vc1.hidesBottomBarWhenPushed=YES;
//如果是在UITabBarController中 使用:
self.tabBar.hidden=YES;
==========================================================
添加子控制器到ITabBarController中 第一种方式 [tb addChildViewController:vc1]; 第二种方式(子控制器添加到啊 tabBarcontroller,tabBarItem立即生成) tb.viewControllers=@[vc1,vc2,vc3,vc4];
设置tabBarItem.title的时候可以用:
[email protected]"首页";
如果用vc1.tabBarItem.title(不起作用)并且用vc1.title时,tabBarItem.title会显示和vc1.title一样的标题;
如果vc1.tabBarItem.title(不起作用)并且用[vc1.navigationItem
setTitle:@"首页"]时,tabBarItem.title显示为空。
设置tabBarItem的标题右上角的数字图标
nav1.tabBarItem.badgeValue=@"123";
设置tabBarItem的标题图片
vc1.tabBarItem.image=[UIImage imageNamed:@"tab_recent_nor"];用这个方法设置标题图片时, nav.tabBarItem.badgeValue=@"123";无效
nav.tabBarItem.image =[UIImageimageNamed:@"menu"];用这个方法设置标题图片时,
nav.tabBarItem.badgeValue=@"123";有效
//普通状态显示的图片
[nav.tabBarItemsetImage:[UIImageimageNamed:@"teachOnlinegray"]];
[vc1.tabBarItem setImage:[UIImage imageNamed:@"teachOnlinegray"]];
//选择状态下显示的图片
[nav.tabBarItemsetSelectedImage:[UIImageimageNamed:@"teachOnlinegreen"]];
[vc1.tabBarItem setSelectedImage:[UIImage imageNamed:@"teachOnlinegreen"]];
====================================================
UITabBarController是IOS中很常用的一个viewController,例如系统的闹钟程序,ipod程序等。UITabBarController通常作为整个程序的rootViewController,而且不能添加到别的container viewController中。
首先我们看一下它的view层级图:
一、手动创建UITabBarController
最常见的创建UITabBarController的地方就是在application delegate中的 applicationDidFinishLaunching:方法,因为UITabBarController通常是作为整个程序的rootViewController的,我们需要在程序的window显示之前就创建好它,具体步骤如下:
1、创建一个UITabBarController对象
2、创建tabbarcontroller中每一个tab对应的要显示的对象
3、通过UITabBarController的viewController属性将要显示的所有content viewcontroller添加到UITabBarController中
4、通过设置UITabBarController对象为window.rootViewController,然后显示window
三、UITabBarItem属性介绍及6种创建方式
我们创建了6个视图控制器,然后把它们的头文件导入进来,所以在AppDelegate.m文件中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //第一种方式:通过导航控制器的tabBarItem来调用image属性 ViewController *vc0=[[ViewController alloc]init]; UINavigationController *nav0=[[UINavigationController alloc]initWithRootViewController:vc0]; //用[email protected]"界面1";来赋值标题时用.title取值取不到, //用以下方式赋值标题,可以用.tabBarItem.title取值,但是以下方式直接把navigationItem.title也一并赋值了 //优先使用以下的方法 nav0.title=@"界面1"; //赋值图片 nav0.tabBarItem.image=[UIImage imageNamed:@"[email protected]"]; //第二种方式:通过视图控制器的tabBarItem使用setFinishedSelectedImage方法,设置选中未选中图片状态 //不过这种方法貌似不被推荐不能使用了,在iOS7中已被抛弃 //所以推荐使用initWithTitle:image:selectedImage:这个初始化方法 ViewController1 *vc1=[[ViewController1 alloc]init]; //[email protected]"界面2"; //[vc1.tabBarItem setFinishedSelectedImage:[UIImage imageNamed:@"[email protected]"] withFinishedUnselectedImage:[UIImage imageNamed:@"[email protected]"]]; UITabBarItem *tb0=[[UITabBarItem alloc]initWithTitle:@"界面2" image:[UIImage imageNamed:@"[email protected]"] selectedImage:[UIImage imageNamed:@"[email protected]"]]; vc1.tabBarItem=tb0; //第三种方式:通过视图控制器的tabBarItem来调用image属性 ViewController2 *vc2=[[ViewController2 alloc]init]; vc2.title=@"界面3"; vc2.tabBarItem.image=[UIImage imageNamed:@"[email protected]"]; //第四种方式:设置徽标,badgeValue是tabBarItem的一个属性,值是字符串 ViewController3 *vc3=[[ViewController3 alloc]init]; vc3.title=@"界面4"; vc3.tabBarItem.image=[UIImage imageNamed:@"[email protected]"]; vc3.tabBarItem.badgeValue=@"6"; //第五种方式:通过先设置一个系统自带的UITabBarItem,再把它赋值给视图控制器的tabBarItem //用这种方式创建后,再设置.title或者.tabBarItem.Image就不起作用了 ViewController4 *vc4=[[ViewController4 alloc]init]; UITabBarItem *tb1=[[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemFavorites tag:0]; vc4.tabBarItem=tb1; //第六种方式:通过先初始化一个带有标题和图片的UITabBarItem,然后把它赋值给视图控制器的tabBarItem //相当于分别对.title和.tabBarItem.image进行设置,效果是类似的 //这种方式不推荐使用 ViewController5 *vc5=[[ViewController5 alloc]init]; UITabBarItem *tb2=[[UITabBarItem alloc]initWithTitle:@"界面6" image:[UIImage imageNamed:@"[email protected]"] tag:1]; vc5.tabBarItem=tb2; //以下是整一个数组装上面的那些个,然后初始化一个UITabBarController再把数组赋值给UITabBarController的viewControllers属性 //最后别忘了,把window的根视图控制器修改一下 NSArray *arr2=[[NSArray alloc]initWithObjects:nav0,vc4,vc1,vc3,vc2,vc5, nil]; UITabBarController *tbCon1=[[UITabBarController alloc]init]; tbCon1.viewControllers=arr2; self.window.rootViewController=tbCon1; // Override point for customization after application launch. return YES; }
UITabBar上面显示的每一个Tab都对应着一个ViewController,我们可以通过设置viewcontroller.tabBarItem属性来改变tabbar上对应的tab显示内容。否则系统将会根据viewController的title自动创建一个,该tabBarItem只显示文字,没有图像。当我们自己创建UITabBarItem的时候,我们可以显示的指定显示的图像和对应的文字描述。当然还可以通过setFinishedSelectedImage:withFinishedUnselectedImage:方法给选中状态和飞选中状态指定不同的图片。下面看个自己创建UITabBarItem的小例子:
UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"Second" image:nil tag:2]; [item setFinishedSelectedImage:[UIImage imageNamed:@"second.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"first.png"]]; viewController2.tabBarItem = item; [item release];
此外UITabBarItem还有一个属性badgeValue,通过设置该属性可以在其右上角显示一个小的角标,通常用于提示用户有新的消息,使用很简单,后面有例子。
三、moreNavigationController
UITabBar上最多可以显示5个Tab,当我们往UITabBarController中添加超过的viewController超过5个时候,最后一个一个就会自动变成,按照设置的viewControlles的顺序,显示前四个viewController的tabBarItem,后面的tabBarItem将不再显示。当点击more时候将会弹出一个标准的navigationViewController,里面放有其它未显示的的viewController,并且带有一个edit按钮,通过点击该按钮可以进入类似与ipod程序中设置tabBar的编辑界面。编辑界面中默认所有的viewController都是可以编辑的,我们可以通过设置UITabBarController的customizableViewControllers属性来指定viewControllers的一个子集,即只允许一部分viewController是可以放到tabBar中显示的。但是这块儿要注意一个问题就是每当UITabBarController的viewControllers属性发生变化的时候,customizableViewControllers就会自动设置成跟viewControllers一致,即默认的所有的viewController都是可以编辑的,如果我们要始终限制只是某一部分可编辑的话,记得在每次viewControlles发生改变的时候,重新设置一次customizableViewControllers。
四、UITabBarController的Rotation
UITabBarController默认只支持竖屏,当设备方向放生变化时候,它会查询viewControllers中包含的所有ViewController,仅当所有的viewController都支持该方向时,UITabBarController才会发生旋转,否则默认的竖向。
此处需要注意当UITabBarController支持旋转,而且发生旋转的时候,只有当前显示的viewController会接收到旋转的消息。
五、UITabBar
尺寸,UITabBarItem有图片icon也有文字,图片是50*50。具体的参数, 点击这里 。
UITabBar自己有一些方法是可以改变自身状态,但是对于UITabBarController自带的tabBar,我们不能直接去修改其状态。任何直接修改tabBar的操作将会抛出异常,下面看一个抛出异常的小例子:
self.tabBarController = [[[UITabBarController alloc] init] autorelease]; self.tabBarController.delegate = self; self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, viewController3, nil]; self.window.rootViewController = self.tabBarController; [self.window makeKeyAndVisible]; self.tabBarController.tabBar.selectedItem = nil;
六、Change Selected Viewcontroller
改变UITabBarController中当前显示的viewController,可以通过一下两种方法:
1、selectedIndex属性
通过该属性可以获得当前选中的viewController,设置该属性,可以显示viewControllers中对应的index的viewController。如果当前选中的是MoreViewController的话,该属性获取出来的值是NSNotFound,而且通过该属性也不能设置选中MoreViewController。设置index超出viewControllers的范围,将会被忽略。
2、selectedViewController属性
通过该属性可以获取到当前显示的viewController,通过设置该属性可以设置当前选中的viewController,同时更新selectedIndex。可以通过给该属性赋值
tabBarController.moreNavigationController可以选中moreViewController。
3、viewControllers属性
设置viewControllers属性也会影响当前选中的viewController,设置该属性时UITabBarController首先会清空所有旧的viewController,然后部署新的viewController,接着尝试重新选中上一次显示的viewController,如果该viewController已经不存在的话,会接着尝试选中index和selectedIndex相同的viewController,如果该index无效的话,则默认选中第一个viewController。
七、UITabBarControllerDelegate
通过代理我们可以监测UITabBarController的当前选中viewController的变化,以及moreViewController中对编辑所有viewController的编辑。通过实现下面方法:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController;
该方法用于控制TabBarItem能不能选中,返回NO,将禁止用户点击某一个TabBarItem被选中。但是程序内部还是可以通过直接setSelectedIndex选中该TabBarItem。
下面这三个方法主要用于监测对moreViewController中对view controller的edit操作
- (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray *)viewControllers; - (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed; - (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed;
1.UITabBar
下方的工具条称为UITabBar ,如果UITabBarController有N个子控制器,那么UITabBar内部就会有N 个UITabBarButton作为子控件与之对应。
注意:UITabBarButton在UITabBar中得位置是均分的,UITabBar的高度为49。
在上面的程序中,UITabBarController有4个子控制器,所以UITabBar中有4个UITabBarButton,UITabBar的结构?大致如下图所示:
2.UITabBarButton
UITabBarButton?面显?什么内容,由对应子控制器的tabBarItem属性来决定
vc1.tabBarItem.title=@"消息"; vc1.tabBarItem.image=[UIImage imageNamed:@"tab_recent_nor"];
注意:展示的顺序和添加的顺序一致,展现在眼前的是第一个添加的控制器对应的View。