UITabBarController詳解


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

   一、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的圖片,如下:

 

 觀察上圖,最下面的那個Tab bar,這是由UITabBarController自己負責維護的,就像UINavigation Bar是由UINavigationController負責維護一樣,不建議被修改,但如果實在需要改變的話,只能通過UITabBarController提供的方法去修改。

   你有沒有發現,絕大多數的iOS程序,如果他用到了UITabBarController,那么他的外觀就像上圖,Tab bar默認在下面,但有時我們又希望將他顯示到最上面去,就像android的聯系人程序一樣,其實只要幾句代碼就行了:

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

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

 

二、一個標准的 tab bar interface 通常由下列對象組成:

1.一個 UITabBarController 對象

2.每一個tab 都必須有一個content view controller(所以UITabBarController有一個屬性是viewControllers)

3.一個可選的delegate對象

注意了:通常而言,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];

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

 

 三、在創建一個tab bar interface之前,你應該考慮清楚程序是否真的需要使用該布局,而且應該在正確的地方使用它……通常通過下面這些方式使用:

1.作為window的root view controller

2.作為 split view interface(iPad專有界面,不知道的可以百度下)中的其中一個一個view controller

3.作為modal view使用

4.作為UIPopoverController(iPad專有)的content view

四、在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

五、當你點擊某個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的話,則肯定是可以選中的。。。

六、其實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相等,希望表達清楚了。。。

七、

看看上面的圖,是不是和應用程序的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;

八、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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM