UITabBarController使用詳解

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];
        // Override point for customization after application launch.
        
     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" p_w_picpath:nil tag:2];
[item setFinishedSelectedImage:[UIImage p_w_picpathNamed:@"second.png"]
     withFinishedUnselectedImage:[UIImage p_w_picpathNamed:@"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這個頭文件,摺疊後加進去,總是無法展開,望大家見諒!
//
//    SvTabBarAppDelegate.h
//    SvTabBarControllerSample
//
//    Created by maple on 5/19/12.
//    Copyright (c) 2012 smileEvday. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface SvTabBarAppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) UITabBarController *tabBarController;

@end

SvTabBarAppDelegate.m

//
//    SvTabBarAppDelegate.m
//    SvTabBarControllerSample
//
//    Created by maple on 5/19/12.
//    Copyright (c) 2012 smileEvday. All rights reserved.
//

#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];
        // Override point for customization after application launch.
        SvTabBarFirstViewController *viewController1, *viewController2, *viewController3;
        SvTabBarFirstViewController *viewController4, *viewController5, *viewController6;
        
        // second kind tabbar controlle
        SvTabBarSecondViewController *viewController7;
        
        // init first tabbarviewcontroller
        viewController1 = [[SvTabBarFirstViewController alloc] initWithNibName:nil bundle:nil];
        viewController1.title = @"First";
        // here set text is in vain, because the vc's view is not load
        //viewController1.contentLbl.text = @"First Tab";
        
        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#" p_w_picpath:nil tag:2];
        [item setFinishedSelectedImage:[UIImage p_w_picpathNamed:@"second.png"]
             withFinishedUnselectedImage:[UIImage p_w_picpathNamed:@"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";
        
        // only support portrait interface, so when you add this vc to tabBarcontroller,
        // the tabbarcontroller will support portrait interface only
        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];
        
        // Directly modifying a tab bar managed by a tab bar controller is not allowed.
//        self.tabBarController.tabBar.selectedItem = nil;
        
        return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
}
*/

/*
// Optional UITabBarControllerDelegate method.
- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed
{
}
*/

#pragma mark -
#pragma mark Btn action

- (void)changToThirdTab
{
        [self.tabBarController setSelectedViewController:[self.tabBarController.viewControllers objectAtIndex:2]];
}

- (void)changToFourthTab
{
        [self.tabBarController setSelectedIndex:3];
}

// set tabbar viewcontrollers will lead customizableViewControllers set to default.(equal to viewcontrollers)
// so if you want to restrict customizableViewControllers, you should reset it when viewcontrollers changed
- (void)setTabBarViewController
{
        self.tabBarController.viewControllers = self.tabBarController.viewControllers;
}

// you can just select more tab by set selectedViewController, set selectedIndex is in vain
- (void)changToMoreTab
{
        [self.tabBarController setSelectedViewController:self.tabBarController.moreNavigationController];
        
        // when set more tab selected, the selectedindex will be NSNotFound
        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
SvTabBarFirstViewController.h

//
//    SvTabBarFirstViewController.h
//    SvTabBarControllerSample
//
//    Created by maple on 5/19/12.
//    Copyright (c) 2012 smileEvday. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface SvTabBarFirstViewController : UIViewController


@end

SvTabBarFirstViewController.m

//
//    SvTabBarFirstViewController.m
//    SvTabBarControllerSample
//
//    Created by maple on 5/19/12.
//    Copyright (c) 2012 smileEvday. All rights reserved.
//

#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.p_w_picpath = [UIImage p_w_picpathNamed:@"first"];
        }
        return self;
}
                                                        
- (void)viewDidLoad
{
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = [UIColor whiteColor];
}

- (void)viewDidUnload
{
        [super viewDidUnload];
        // Release any retained subviews of the main view.

}

- (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
SvTabBarSecondViewController.h

//
//    SvTabBarSecondViewController.h
//    SvTabBarControllerSample
//
//    Created by maple on 5/19/12.
//    Copyright (c) 2012 smileEvday. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface SvTabBarSecondViewController : UIViewController

@end

SvTabBarSecondViewController.m

//
//    SvTabBarSecondViewController.m
//    SvTabBarControllerSample
//
//    Created by maple on 5/19/12.
//    Copyright (c) 2012 smileEvday. All rights reserved.
//

#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.p_w_picpath = [UIImage p_w_picpathNamed:@"second"];
        }
        return self;
}
                                                        
- (void)viewDidLoad
{
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = [UIColor greenColor];
}

- (void)viewDidUnload
{
        [super viewDidUnload];
        // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
        //return (interfaceOrientation == UIInterfaceOrientationPortrait);
        return YES;
}

@end

原文出處:http://www.cnblogs.com/smileEvday/archive/2012/05/20/UITabBarController.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章