UITabBarController詳解

  當咱們想要作一個界面相似 聯繫人 那樣的程序時,就必定會用到 UITabBar,它能夠幫咱們添加、管理許多的Tab項, 使咱們的程序包含不一樣的操做模式,因爲管理UITabBar可能會有些麻煩,因此apple也幫咱們對其進行了封裝,產生了簡單好用的UITabBarController,就像UITableViewController對UITableView的封裝,只不過在用到UITabBarController時,咱們不用像使用UITableViewController那樣去繼承它。html

   1、UITabBarController主要用來管理你提供的content view controllers,而每個 content view controller則負責管理本身的view層級關係,一般,當你的程序想要提供一些平行(同一個等級的)的不一樣界面,而剛好這些界面使用到的數據是一類的,或者功能是一個系列的,那 tab bar interface 是很是有用的.     在這樣的 tab bar interface界面中,你能夠設置許多的 tab ,每個 tab則必定要指定一個content view controller,當某個tab被點擊時,UITabBarController就會選中該tab而且顯示該viewController所持有的content view.在apple官網上有一張關於UITabBarController的圖片,以下:android

 

 觀察上圖,最下面的那個Tab bar,這是由UITabBarController本身負責維護的,就像UINavigation Bar是由UINavigationController負責維護同樣,不建議被修改,但若是實在須要改變的話,只能經過UITabBarController提供的方法去修改。ios

   你有沒有發現,絕大多數的iOS程序,若是他用到了UITabBarController,那麼他的外觀就像上圖,Tab bar默認在下面,但有時咱們又但願將他顯示到最上面去,就像android的聯繫人程序同樣,其實只要幾句代碼就好了:數組

CGRect frame = CGRectMake(0, 20, 320, 44)    tabBarController.tabBar.frame = frame;app

呵呵,這樣不就能夠了,你想放哪放哪,不過可別太難看了。ide

 

2、一個標準的 tab bar interface 一般由下列對象組成:佈局

1.一個 UITabBarController 對象spa

2.每個tab 都必須有一個content view controller(因此UITabBarController有一個屬性是viewControllers)代理

3.一個可選的delegate對象code

注意了:一般而言,UITabBarController通常做爲應用程序的rootViewController,並且它不能做爲UINavigationController的rootViewController.

因此初始化的代碼通常這樣寫:

self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    ViewControllerA *A  = [[ViewControllerA alloc]initWithNibName:@"ViewControllerA" bundle:nil];
    ViewControllerB *B  = [[ViewControllerB alloc]initWithNibName:@"ViewControllerB" bundle:nil];
    ViewControllerC *C  = [[ViewControllerC alloc]initWithNibName:@"ViewControllerC" bundle:nil];
    ViewControllerD *D  = [[ViewControllerD alloc]initWithNibName:@"ViewControllerD" bundle:nil];
    ViewControllerE *E  = [[ViewControllerE alloc]initWithNibName:@"ViewControllerE" bundle:nil];
    
    UITabBarController *tabBarController = [[UITabBarController alloc]init];
    
    A.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemBookmarks tag:0];
    self.viewController.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemContacts tag:1];
    B.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemDownloads tag:2];
    C.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemHistory tag:3];
    D.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemSearch tag:4];
    E.tabBarItem = [[UITabBarItem alloc]initWithTabBarSystemItem:UITabBarSystemItemTopRated tag:5];
  
    tabBarController.viewControllers = @[self.viewController,A,B,C,D,E];
    tabBarController.customizableViewControllers = @[B,C,D,E];
    [tabBarController setSelectedIndex:2];
    tabBarController.delegate = self;
//    CGRect frame = CGRectMake(0, 20, 320, 44);
//    tabBarController.tabBar.frame = frame;

    self.window.rootViewController = tabBarController;

你應該像上面那樣,爲每個viewController指定一個tabBarItem,固然你也能夠這樣初始化

  A.tabBarItem = [[UITabBarItem alloc]initWithTitle:<#(NSString *)#> image:<#(UIImage *)#> tag:<#(NSInteger)#>];

從而達到自定義tab bar item外觀的目的,而沒必要使用系統提供好的,但此時你使用的圖片大小要有規定了,通常ipad在60*60,iPhone在30*30左右,

能夠參考連接https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/IconsImages/IconsImages.html

再來看下面這張圖,它描繪了UITabBarController和它的屬性viewControllers、customizableViewControllers和selectedViewController等的關係

 

 

若是你的viewControllers屬性添加了多於五個的items,那tab bar controller將會自動插入一個特殊的view controller,稱爲 More view controller,該 controller 將會負責管理多於的items,這個More view controller提供一個自定義的界面,用table的方式呈現多餘的view controller,而且view controller的數量是不限制的。對於這個more view  controller ,UITabBarController 經過一個屬性----moreNavigationController持有它的引用,但看名字就知道他是一個UINavigationController對象,全部咱們能夠修改它的一些屬性,如:

UINavigationController *nav = tabBarController.moreNavigationController;

[nav setNavigationBarHidden:YES];

固然,如不是必須,最好不要修改它。

 

 3、在建立一個tab bar interface以前,你應該考慮清楚程序是否真的須要使用該佈局,並且應該在正確的地方使用它……一般經過下面這些方式使用:

1.做爲window的root view controller

2.做爲 split view interface(iPad專有界面,不知道的能夠百度下)中的其中一個一個view controller

3.做爲modal view使用

4.做爲UIPopoverController(iPad專有)的content view

4、在tab bar interface建立好後,咱們能夠用代碼動態的修改它,如:增長或刪除tab項,對於這種操做,一般咱們須要從新指派UITabBarController的viewConrollers屬性來進行,有人可能要問了,爲何要從新指派,viewController不是一個數組嗎,不能直接經過數組的remove方法直接刪除嗎,可別忘了,這個屬性的類型是個NSArray,不能進行刪除,添加的。咱們知道,當tab bar interface界面顯示後,咱們只能在某一時刻操做一個界面,所以,修改viewControllers屬性必須在某個content viewController中完成,咱們能夠經過UIViewController的屬性 tabBarController來得到UITabBarController的引用,就像得到UINavigationController的引用同樣,修改代碼以下:

NSMutableArray* newArray = [NSMutableArray arrayWithArray:self.tabBarController.viewControllers];
      [newArray removeObject:self];
 
      [self.tabBarController setViewControllers:newArray animated:YES];
View Code

5、當你點擊某個tab項時,它對應的content viewController會獲得顯示,

但有時也許咱們就是不但願某個被你點擊的view獲得顯示,如:某個viewController所需的數據尚未完成加載,或者必須等某個登錄界面 完成登錄後

才能激活其餘viewController,此時你能夠實現UITabBarControllerDelgate中的方法

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController NS_AVAILABLE_IOS(3_0)

經過設置返回值來禁止某個viewController可否被選中,以下:

- (BOOL)tabBarController:(UITabBarController *)aTabBar
         shouldSelectViewController:(UIViewController *)viewController
{
   if (![self hasValidLogin] && (viewController != [aTabBar.viewControllers objectAtIndex:0]) )
   {
      // Disable all but the first tab.
      return NO;
   }
 
   return YES;
}
View Code

固然你也能夠經過代碼手動去選擇某個viewController,只要設置UITabBarController的屬性selectedViewController 或者 selectedIndex(從0開始),但此時代理的方法是無效的,也就是說,若是你經過代碼來選中某個viewController的話,則確定是能夠選中的。。。

6、其實UITabBarController還容許你對viewControllers進行排序,你可使任意一個viewController出如今第一個tab項中,上面咱們有提到moreNavigationController,當tabs超過5個時,也就是viewControllers的個數超過5個時,最後一個的tab item默認爲more,而後那些沒能顯示在tab上的viewController即可經過moreNavigationController以列表的形勢顯示,那是否是那些沒能在tab上顯示的viewController就永遠只能在moreNavigationController的列表中顯示了??固然不是,當我麼點擊more   tab時會出現下面左圖的界面,而後再點擊navigationBar左邊的編輯按鈕時會出現下面的右圖,此時你能夠把這些顯示的tab直接拉到下面的 tab bar中,從而達到自定義tab的功能

那若是我但願某個viewController一直在tab上顯示,二不但願用戶將其排列到more tab中去,那該怎麼辦呢。。。。UITabBarController有個屬性customizableViewControllers

 由它來決定哪些viewController容許重排列。。不過這裏要注意了,默認狀況下customizableViewControllers 和 viewControllers屬性包含的內容是同樣的,你能夠手動設置它爲viewControllers的字集(只能是字集),但當你從新更新了viewControllers時,customizableViewControllers又會默認和viewControllers相等,但願表達清楚了。。。

7、

看看上面的圖,是否是和應用程序的badge很像,當某個tab有信息須要你處理時,顯示這個能很好的引發用戶的注意,而你只需這樣作

if (numberOfNewItems == 0)
   self.tabBarItem.badgeValue = nil;
else
   self.tabBarItem.badgeValue = [NSString stringWithFormat:@"%d", numberOfNewItems];

self 是 viewContrller ,不過要注意了,這裏的badgeValue是個NSString類型的,不要和下面的弄混了

[UIApplication sharedApplication].applicationIconBadgeNumber = 2

 一般狀況下,當咱們點擊顯示了badge的那個tab後,這個紅色的提示就應該消失。呵呵,可別忘了,當你切換tab時,viewController的聲明週期但是同樣的,它會執行那些

viewDidAppear 、viewDidDisappear等方法,因此最好的辦法就是在該viewContrller的

-(void)viewDidAppear:(BOOL)animated方法中,將其重置爲空,

如:self.tabBarItem.badgeValue = nil;

8、UITabBarController是否能旋轉呢?那要看它的那些viewControllers了,若是在viewControllers中只要有一個viewController不支持某個方向的旋轉,那UITabBarControlelr就也不能旋轉到該方向。再來看看它的一些代理方法,我就簡單描述下:

//當你選中某個tab 項時調用,咱們能夠在這裏作一些操做,如隱藏狀態欄,導航欄什麼的。

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController

//當點擊more後出現moreNavigationController畫面時,點擊那個edit按鈕時觸發

- (void)tabBarController:(UITabBarController *)tabBarController willBeginCustomizingViewControllers:(NSArray *)viewControllers NS_AVAILABLE_IOS(3_0)

//下面兩個方法在點擊那個done按鈕時觸發

- (void)tabBarController:(UITabBarController *)tabBarController willEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed NS_AVAILABLE_IOS(3_0)

 

- (void)tabBarController:(UITabBarController *)tabBarController didEndCustomizingViewControllers:(NSArray *)viewControllers changed:(BOOL)changed

相關文章
相關標籤/搜索