转自http://www.cnblogs.com/smileEvday/archive/2012/05/20/UITabBarController.html
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
下面看一个简单的例子:
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
-
-
- SvTabBarFirstViewController *viewController1, *viewController2;
-
- viewController1 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
- viewController1.title = @"First";
-
- viewController2 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
- viewController2.title = @"Second";
-
- self.tabBarController = [[[UITabBarController alloc] init] autorelease];
- self.tabBarController.delegate = self;
- self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
-
- [viewController1 release];
- [viewController2 release];
-
- self.window.rootViewController = self.tabBarController;
- [self.window makeKeyAndVisible];
-
- return YES;
- }
二、UITabBarItem
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
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;
上面代码的最后一行直接修改了tabBar的状态,运行程序回得到如下结果:

六、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;
七、附件UITabBarController测试程序源码
SvTabBarAppDelegate.h这个头文件,折叠后加进去,总是无法展开,望大家见谅!
-
-
-
-
-
-
-
-
- #import <UIKit/UIKit.h>
-
- @interface SvTabBarAppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
-
- @property (strong, nonatomic) UIWindow *window;
-
- @property (strong, nonatomic) UITabBarController *tabBarController;
-
- @end
-
-
-
-
-
-
-
-
- #import "SvTabBarAppDelegate.h"
-
- #import "SvTabBarFirstViewController.h"
- #import "SvTabBarSecondViewController.h"
-
- @implementation SvTabBarAppDelegate
-
- @synthesize window = _window;
- @synthesize tabBarController = _tabBarController;
-
- - (void)dealloc
- {
- [_window release];
- [_tabBarController release];
- [super dealloc];
- }
-
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
-
- SvTabBarFirstViewController *viewController1, *viewController2, *viewController3;
- SvTabBarFirstViewController *viewController4, *viewController5, *viewController6;
-
-
- SvTabBarSecondViewController *viewController7;
-
-
- viewController1 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
- viewController1.title = @"First";
-
-
-
- UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- btn.frame = CGRectMake(0, 0, 150, 70);
- btn.center = CGPointMake(160, 120);
- btn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
- [btn setTitle:@"Change to Third" forState:UIControlStateNormal];
- [btn addTarget:self action:@selector(changToThirdTab) forControlEvents:UIControlEventTouchUpInside];
- [viewController1.view addSubview:btn];
-
- btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- btn.frame = CGRectMake(0, 0, 150, 70);
- btn.center = CGPointMake(160, 240);
- btn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
- [btn setTitle:@"Change to MoreVC" forState:UIControlStateNormal];
- [btn addTarget:self action:@selector(changToMoreTab) forControlEvents:UIControlEventTouchUpInside];
- [viewController1.view addSubview:btn];
-
- btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- btn.frame = CGRectMake(0, 0, 150, 70);
- btn.center = CGPointMake(160, 360);
- btn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
- [btn setTitle:@"Set ViewController" forState:UIControlStateNormal];
- [btn addTarget:self action:@selector(setTabBarViewController) forControlEvents:UIControlEventTouchUpInside];
- [viewController1.view addSubview:btn];
-
- viewController2 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
- viewController2.title = @"Second";
- btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- btn.frame = CGRectMake(0, 0, 150, 70);
- btn.center = CGPointMake(160, 120);
- btn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
- [btn setTitle:@"Change to Fourth" forState:UIControlStateNormal];
- [btn addTarget:self action:@selector(changToFourthTab) forControlEvents:UIControlEventTouchUpInside];
- [viewController2.view addSubview:btn];
-
- btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- btn.frame = CGRectMake(0, 0, 150, 70);
- btn.center = CGPointMake(160, 240);
- btn.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
- [btn setTitle:@"Set Badge" forState:UIControlStateNormal];
- [btn addTarget:self action:@selector(setBadge) forControlEvents:UIControlEventTouchUpInside];
- [viewController2.view addSubview:btn];
-
-
- viewController3 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
- viewController3.title = @"Third";
- UITabBarItem *item = [[UITabBarItem alloc] initWithTitle:@"#3#" image:nil tag:2];
- [item setFinishedSelectedImage:[UIImage imageNamed:@"second.png"]
- withFinishedUnselectedImage:[UIImage imageNamed:@"first.png"]];
- viewController3.tabBarItem = item;
- [item release];
-
- viewController4 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
- viewController4.title = @"Fourth";
-
- viewController5 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
- viewController5.title = @"Fifth";
-
- viewController6 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
- viewController6.title = @"Sixth";
-
-
-
- viewController7 = [[SvTabBarSecondViewController alloc] initWithNibName:nil bundle:nil];
-
- self.tabBarController = [[[UITabBarController alloc] init] autorelease];
- self.tabBarController.delegate = self;
- self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, viewController3,
- viewController4, viewController5, viewController6, viewController7, nil];
- self.tabBarController.customizableViewControllers = [NSArray arrayWithObjects:viewController1, viewController2, viewController3,
- viewController4, nil];
-
- [viewController1 release];
- [viewController2 release];
- [viewController3 release];
- [viewController4 release];
- [viewController5 release];
- [viewController6 release];
- [viewController7 release];
-
- self.window.rootViewController = self.tabBarController;
- [self.window makeKeyAndVisible];
-
-
-
-
- return YES;
- }
-
- - (void)applicationWillResignActive:(UIApplication *)application
- {
-
-
- }
-
- - (void)applicationDidEnterBackground:(UIApplication *)application
- {
-
-
- }
-
- - (void)applicationWillEnterForeground:(UIApplication *)application
- {
-
- }
-
- - (void)applicationDidBecomeActive:(UIApplication *)application
- {
-
- }
-
- - (void)applicationWillTerminate:(UIApplication *)application
- {
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #pragma mark -
- #pragma mark Btn action
-
- - (void)changToThirdTab
- {
- [self.tabBarController setSelectedViewController:[self.tabBarController.viewControllers objectAtIndex:2]];
- }
-
- - (void)changToFourthTab
- {
- [self.tabBarController setSelectedIndex:3];
- }
-
-
-
- - (void)setTabBarViewController
- {
- self.tabBarController.viewControllers = self.tabBarController.viewControllers;
- }
-
-
- - (void)changToMoreTab
- {
- [self.tabBarController setSelectedViewController:self.tabBarController.moreNavigationController];
-
-
- NSLog(@"%d", self.tabBarController.selectedIndex);
- }
-
- - (void)setBadge
- {
- self.tabBarController.selectedViewController.tabBarItem.badgeValue = @"2";
- }
-
- #pragma mark-
- #pragma mark UITabBarcontrollerDelegate
-
- - (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray *)viewControllers
- {
- NSLog(@"willBeginCustomizingViewControllers: %@", viewControllers);
- }
-
- - (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
- {
- NSLog(@"viewcontrollers: %@, ischanged: %d", viewControllers, changed);
- }
-
-
- - (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
- {
- NSLog(@"didEndCustomizingViewController!");
- NSLog(@"didEndCustomizingViewController: %@, ischanged: %d", viewControllers, changed);
- }
-
- - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
- {
- if ([tabBarController.viewControllers indexOfObject:viewController] != 2) {
- return YES;
- }
- return NO;
- }
-
- - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
- {
- NSLog(@"didSelectViewController!");
- }
-
- @end
-
-
-
-
-
-
-
-
- #import <UIKit/UIKit.h>
-
- @interface SvTabBarFirstViewController : UIViewController
-
-
- @end
-
-
-
-
-
-
-
-
- #import "SvTabBarFirstViewController.h"
-
- @interface SvTabBarFirstViewController ()
-
- @end
-
- @implementation SvTabBarFirstViewController
-
-
- - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
- {
- self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
- if (self) {
-
- self.tabBarItem.image = [UIImage imageNamed:@"first"];
- }
- return self;
- }
-
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
- self.view.backgroundColor = [UIColor whiteColor];
- }
-
- - (void)viewDidUnload
- {
- [super viewDidUnload];
-
-
- }
-
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
- return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
- } else {
- return YES;
- }
- }
-
- - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
- {
- NSLog(@"%@ rotate!", self.title);
- }
-
- - (NSString*)description
- {
- return [NSString stringWithFormat:@"title: %@", self.title];
- }
-
- @end
-
-
-
-
-
-
-
-
- #import <UIKit/UIKit.h>
-
- @interface SvTabBarSecondViewController : UIViewController
-
- @end
-
-
-
-
-
-
-
-
- #import "SvTabBarSecondViewController.h"
-
- @interface SvTabBarSecondViewController ()
-
- @end
-
- @implementation SvTabBarSecondViewController
-
- - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
- {
- self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
- if (self) {
- self.tabBarItem.image = [UIImage imageNamed:@"second"];
- }
- return self;
- }
-
- - (void)viewDidLoad
- {
- [super viewDidLoad];
-
- self.view.backgroundColor = [UIColor greenColor];
- }
-
- - (void)viewDidUnload
- {
- [super viewDidUnload];
-
- }
-
- - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
- {
-
- return YES;
- }
-
- @end
顺便粘上这篇博客博主的主页
http://blog.csdn.net/mamong