zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    MySQL存储过程
    [转载]JDBC应该始终以PreparedStatement代替Statement
    Restlet入门例子 RESTful web framwork for java
    Cglib的使用方法(3)Mixin
    HDOJ_1220
    精华:OracleHelper类
    web.config详解
    ADO.NET结构
    字典树
    WCF、Net remoting、Web service概念及区别
  • 原文地址:https://www.cnblogs.com/ctaodream/p/3307745.html
Copyright © 2011-2022 走看看