IOS:UI设计之UINavigationController,NavigationBar,ToolBAR相关基础

 

  基本概念:导航视图控制器(UINavigationController)是用于构建分层应用程序的主要工具,管理着多个内容视图的换入和换出,并且自身提供了视图切换的动画效果(例如:相册,QQ,微信等APP应用)。

  它的父类是UIViewController,是所有视图控制器的基类,导航控制器以栈的形式来实现,其本身也属于视图控制器。

  

  下图是UINavigationController的分层结构图:

  

              UINavigationController view层级

  栈的基本概念与性质:

    栈是一种数据结构,采用先进后出(后进先出)的原则。导航以栈的形式来管理视图控制器,任何视图控制器都可以放入栈中。

    向栈里添加一个对象的操作称为“入栈(push)”,即把对象推入到栈里;

    第一个入栈的对象,通常被叫做“基栈”;最后一个入栈的对象,叫做“栈顶”;

    在栈中删除一个对象的操作叫做“出栈(pop)”;

    当前显示的视图控制器,即为“栈顶”。选择“返回”时,这个视图控制器就“出栈”了。

  导航控制器的基本样式:

    红色部分为:导航控制器的导航栏(NavigationBar)一般来说主要负责视图的弹出和控制主视图;

    黄色部分为:导航控制器显示的主视图区,主要显示内容(用户感兴趣的区域);

    蓝色部分为:导航控制器的工具栏(UIToolBar),默认是隐藏的;

    这些视图共同构成了导航控制器。

      

  下面用一个实例来简单的介绍导航控制器(UINavigationController)的使用方法:

  实现:1.在根视图中间添加一个按钮,名称:“Push”。将标题设置为“RootVC”;

     2.当单击“Push”按钮时,推送到下一个视图控制器;

     3.第二个视图控制器标题“SecondVC”,在视图中间初始化一个“isHidden”按钮,将ToolBar显示出来;

     4.单击按钮时,隐藏导航栏和工具栏目;

 

  实现代码:

    //1.先创建一个空白项目

    //2.新建一个类:命名为“rootViewController”,继承自“UIViewController”

    //3.新建第二个类:命名为“SecondViewController”,继承自“UIViewController”

    Xcode5.1

    //4.层级关系:AppDelegate.h -> rootViewController.h -> SecondViewController.h

    //5.把rootViewController设为UINavigationController的“基栈”:

      //在AppDelegate.m的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;方法里添加代码:

  rootViewController *rootVC = [[rootViewController alloc] init];  //简单的初始化视图控制器

  UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:rootVC];  //初始化并把rootVC定为导航控制器的“基栈”

  self.window.rootViewController = navigation;    //把navigation添加到根视图控制器上

    //6.设置rootViewController的属性;

      //在rootViewController.m里覆盖方法同时添加按钮事件:

  -(void)loadView

  {

        //中间主要的显示视图:

    UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];

    seld.view =view;

    view.backgroundColor = [UIColor yellowColor];

        //标题:

    self.title = @"rootVC";    

        //添加按钮:

    UIButton  *button = [UIButton buttonWithType:UIButtonTypeSystem];

    button.frame = CGRectMake(90,100,140,40);

    [self.view addSubview:button];

    [button setTitle:@"Push" forState:UIControlStateNormal];

    [button addTarget:self action:@selector(PushVC)  forControlEvents:UIControlEventTouchUpInside];

  } 

  -(void)PushVC

  {

    SecondViewController *secondVC = [[SecondViewController alloc] init];

    [self.navigationController  pushViewController:secondVC  animated:YES];    //此方法是导航控制器的推送方法,有1.回到“基栈”popToRootViewController);2.去指定的视图控制器popToViewController);3.压入一个视图pushViewController);4.返回上一个视图popViewControllerAnimated);

  }

 

          //7.设置SecondViewController的属性及方法

              //在SecondViewController.m里添加:

  -(void)loadView

  {

              //主视图显示:

    UIView *SecondVC = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] ];

    [self.view addSubView:SecondVC];

    SecondVC.backgroundColor = [UIColor darkGrayColor];

             //标题:

    self.title = @"SecondVC";    

             //isHidden按钮:

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];

    button.frame = CGRectMake(90,100,140,40);

    [button setTitle:@"isHidden" forState:UIControlStateNormal];

    [button addTarget:self  action:@selector(isHidden) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubView:button];

  }

   //isHidden事件方法,第一次出现时:Toolbar与NavigationBar同时显示出来,当点击按钮后两者隐藏,再次点击后两者显现....

  -(void)isHidden

  {

    if (self.navigationController.toolbarHidden) {

          [self.navigationController setToolbarHidden:NO animated:YES];    //隐藏工具栏(下面)默认是YES(隐藏的)

          [self.navigationController setNavigationBarHidden:NO animated:YES];  //隐藏导航栏(上面)默认是NO(不隐藏的)

        }else{

          [self.navigationController setToolbarHidden:YES animated:YES];

        [self.navigationController setNavigationBarHidden:YES animated:YES];

    }

   //以上代码完成实现目的

   

    

 

 

   导航栏(UINavigationBar)的基本概念:

    一个导航控制器包含有四个对象:UINavigationController;UINavigationBar;UIViewController;UINavigationItem;

    其中NavigationItem存放在UINavigationBar上;

    一个视图控制器(UINavigationController)只有一个导航栏(UINavigationBar),却包含若干个视图控制器(UIViewController);

    UINavigationItem放在UINavigationBar上,但是UINavigationItem不受UINavigationBar的控制,是由每一个视图控制器(UIViewController)来控制它,且一个视图控制器(UIViewController)控制一个UINavigationItem;

    (细细体味一下以上概述,理清UINavigationController,UINavigationBar,UIViewController,UINavigationItem之间的关系!)  

 

  定制导航栏:

    定制标题视图:通过NavigationItem的titleView属性,定制标题视图。titleView属性是一个视图类,因此可以添加一个UIView的实例,也可以添加UIView子类,还可以在UIView的实例中添加子视图。

    //   navigationItem.titleView常用属性,添加一个视图作标题

    UIView *cVIew = [[UIView alloc] initWithFrame:CGRectMake(0,0,160,44);

    cView.backgroundColor = [UIColor redColor];

    self.navigationItem.titleView = cView;    //self 指的是视图控制器

    [cView release];    

    //或者直接用文字标题:

    self.title = @"cView";  //self 指UINavigationController

    //系统给出了了几种navigationBar样式,但在IOS7系统上时,这几种样式就变成两种了(这就是小编还有很多果粉不喜IOS7的缘由,系统强大了,但没有了华丽感)

    self.navigationController.navigationBar.barStyle = UIBarStyleDefault; //在IOS6中对应一个蓝色渐变背景,IOS7中是个灰色背景

    self.navigationController.navigationBar.barStyle = UIBaeStyleBlack;  //在IOS6中对应一个不透明的黑色背景,IOS7中是黑色背景

    self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque; //等于UIBaeStyleBlack样式,但规定为弃用类型

    self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent; //同上面样式一样,也为弃用类型,但是透明

    //这是自定义navigationBar背景的方法,使得navigationBar样式不会太过单调

    [navigationBar setBackgroundImage:[UIImage imageNamed:@"name.png"] forBarMetrics:UIBarMetricsDefault];

    (setBackgroundImage方法的两个参数,需要解释一下:

    UIBarMetricsDefault:用竖着(拿手机)时UINavigationBar的标准的尺寸来显示UINavigationBar

    UIBarMetricsLandscapePhone:用横着时UINavigationBar的标准尺寸来显示UINavigationBar

    )  

    //下面是设置navigationBar背景颜色的方法,其中注意:在IOS6中,设置backgroundColor,是设置背景颜色;在IOS7上,是设置backButton的title字体颜色

    self.navigationController.navigationBar.backgroundColor = [UIColor  redColor];

    //IOS7中设置navigationBar的背景颜色方法是:

    [[UINavigationBar appearancesetBarTintColor:[UIColor redColor]];

     // 修改导航控制器背景图片的方式(IOS5以上)

    [[UINavigationBar appearance] setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];

    注: 通过appearance可以设置全局的控件初始化外观.不过在初始化成功以后,有单独样式需求亦可用同样的方法修改.

      UINavigationBar的标准高度是44,在iOS7之前可以通过44+X的方式实现背景+阴影的效果.从iOS7以后就不行了.

      iOS7对UINavigationBar的标准进行重新的定义,其高度可以延伸到状态栏.所以44+20的高度等于64.

      而刚刚说的44+X方式不再适用于iOS7,iOS7的新规范是64+1.背景图和阴影将单独来设定,代码如下:

    //iOS7 新背景图片设置方法 高度 必需是 64

    [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"name.png"] forBarPosition:UIBarPositionTopAttached barMetrics:UIBarMetricsDefaulr];   

    //iOS7 阴影需单独设定 UIColor clearColor 是去掉字段 1像素阴影  

    [self.navigationController.navigationBar setShadowImage:[UIImage imageWithColor:[UIColor clearColor]]];

    定制左右栏目:通过对导航栏的结构,我们了解到NavigationItem实例中有一个leftBarButtonItem(左)和rightBarButton(右),而这两个属性又是一个UIBarButtonItem的实例,因此,通过初始化UIBarButtonItem实例,设置导航栏的左,右栏目项。

  例:左栏目:

    UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self  action:@selector(leftButton:)];          //初始化一个Item

    self.navigationItem.leftBarButtonItem = leftButton;     //把名字叫“leftButton”的Item设为:leftBarButtonItem 

    backButtonItem.title = @"返回";    //默认情况下“backButton”的标题是前一个视图控制器的title

  -(void)leftButton:(id)sender

    {

      //action

    }

    右栏目:

    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd  target:self action:@selector(selectRightAction:)];  

     self.navigationItem.rightBarButtonItem = rightButton;    //self 指的是UINavigationController

  -(void)rightButton:(id)sender

    {

      //action

    }

    (其中重点介绍下,系统带了很多种UIBarButtonItem的风格,可以参照下图(图来自网络):)

    

 

        

    self.navigationController.navigationBar.wantsFullScreenLayout = YES;  //viewController的一个属性,这个属性默认值是NO,如果设置为YES的话,如果statusbar,navigationbar, toolbar是半透明的话,viewController的view就会缩放延伸到它们下面,但注意一点儿tabBar不在范围内,即无论该属性是否为YES,view都不会覆盖到tabbar的下方。

 

  导航控制器中的工具栏:

    在导航控制器中会有一个UIToolBar的实例,但默认是隐藏的,若需要显示,需要通过以下方法将其打开:

      [self.navigationController  setToolbarHidden:NO animated:YES];  //显示

    导航控制器拥有只有一个UIToolBar实例,但UIToolBar所拥有的UIBarButtonItem实例是视图控制器管理的。

    例如:

      [self setToolbarItems:itemsArray animated:YES];  //将UIBarButtonItem放入数组中,最后添加至UIToolBar中,self 指视图控制器

      [self.navigationController.toolbar setItems:itemsArray animated:YES];  //此代码UIBarButtonItem不会出现在UIToolBar中,且toolbar是只读属性

 

    自定义一个toolbar:

      UIToolBar *toolbar = [[UIToolBar alloc] initWithFrame:CGRectMake(0,460-44*2,320,44)];

      toolbar.barStyle = UIBarMetricsDefault;  //系统风格跟navigationBar一样

      [self.view addSubView:toolbar];    //在“基栈”下添加

      [toolbar release];    //释放内存

    //toolbar作为navigationController的工具栏,少不了的就是各种工具,在toolbar添加工具一般是定义一个数组,然后把数组添加到toolbar里面去

      NSArray *array = @[addItem,titleItem,saveItem];    //"[]"里面的是UIBarButtonItem类的对象,不用“alloc”,默认是“autoRelease”的

      [toolBar setItems:array animated:YES];     //把数组添加到toolbar里面,成为工具

      //还有一种设置方法,不过系统默认导航视图控制器的toolbar是隐藏的,使用要先设置显示:

      [self.navigationController setToolbarHidden:NO animated:YES];

      [self setToolBarItems:array animated:YES];    //self 指的是视图控制器,若使用这个方法就不需要自己初始化一个UIToolBar

      //容易犯的错误写法(需要知道的是:一个视图控制器对应一个navigationBar和一个toolbar):

      [self.navigationController.toolbar setItems:array animated:YES];  //这样被会认为每个页面上的toolbar都一样

    //添加进去的“工具”在显示上的排列是顺序排列,间隔是系统规定的,但相对与整个toolbar来说没有相对于视图的间隔,所以需要自己设置

      UIBarButtonItem *jiange = [[UIBarButtonItem alloc] initWithBarButtonAystemItem:UIBarButtonSystemItemFexibleSpace target:self action:nil];        //此系统风格,作用:使两个Item等分toolbar的视图宽度

   改正:NSArray *array = @[addItem,jiange,titleItem,jiange,saveItem];

      [toolBar setItems:array animated:YES];

    //自定义间隔,如上,只是风格方法不同

      UIBarButtonItem *zdjiange = [[UIBarButtonItem alloc]                             initWithBarButtonAystemItem:UIBarButtonSystemItemFixedSpace target:self action:nil];    //自己常识一下其它的风格

      zdjiange.with = 20;

     (toolbar的使用基本上就是这些,其实跟navigationBar有点相似,只是间隔需要设置,可以多添加几个Item,其它的属性不用全部掌握,可以查API)

 

 

(可能学得比较浅,大家要是有补充可以留言,有问题的大家一起探讨下,可以私下联系:QQ790444804    微信:hgwchihuo

 

                                                -------我是快乐的小尾巴`(*∩_∩*)′)

 

posted @ 2015-05-14 04:52  D黄大炜  阅读(2950)  评论(0编辑  收藏  举报