zoukankan      html  css  js  c++  java
  • 转帖:iOS UINavigationController 对象

    原文地址:http://www.cnblogs.com/smileEvday/archive/2012/05/10/2495153.html

    UINavigationController是iOS编程中比较常用的一种容器view controller,很多系统的控件(如UIImagePickerViewController)以及很多有名的APP中(如qq,系统相册等)都有用到。

    UINavigationController view层级

    当应用通过 UINavigationController 显示多个屏幕的信息时 ,相应的 UINavigationController 对象会以栈的形势保存所有的屏幕,这里的栈其实是一个 NSArray 对象,数组对象中保存的都是 UIViewController 对象。

    一个 UIViewController 对象的视图保存一个屏幕,只有位于栈顶的 UIViewController 对象,其视图才是可见的

    初始化 UINavigationController 实例时,需要传入一个 UIViewController 实例,这个 UIViewController 实例称为 “根视图控制对象( root view controller )”。--- 根视图控制对象位于桟底(如果栈里只有一个对象,根视图控制对象也可以位于栈顶)。

    下图拥有两个视图控制对象的 UINavigationController 实例:

    向 UINavigationController 对象发送 topViewController 消息,可以得到当前位于栈顶的 UIViewController 对象;发送 viewControllers 消息,可以得到整个栈(返回一个 NSArray 对象),viewControllers 数组是有序的,根视图控制器是第一项,栈顶的视图控制对象是最后一想。

    UINavigationContoller 也是 UIViewController 的子类,有自己的视图。 UINavigationController 的视图至少有两个视图:一个是 UINavigationBar 对象,另一个是 topViewController 的视图

    实例对象图:

    UINavigationBar 标题设置:

    UIViewController 对象有一个 navigationItem 属性,类型为 UINavigationItem 。和 UINavigationBar 不同,UINavigationItem 不是 UIView 子类,不能在屏幕上显示。

    UINavigationItem 对象为 UINavigationBar 对象提供绘图所需的内容。当某个 UIViewController 对象成为 UINavigationController 的栈顶对象时, UINavigationBar 对象会使用 UIViewController 对象的 navigationItem 属性设置相应的属性:

    图例:

    ------------------------------------------------------------------------------------------------

    除了 title 字符串外, UINavigationItem 对象还可以包含其他内容,包含: leftBarButtonItem,rightBarButtonItem和 titleView 三个可以自定义的部分。

    leftBarButtonItem 和 rightBarButtonItem 都是指针,指向 UIBarButtonItem 实例。该实例包含按钮信息,此类按钮只能在 UINavigationBar 或 UIToolbar 上显示:

    如图:

    和 UINavigationItem 类似, UIBarButtonItem 也b不是 UIView 子类,只提供 UINavigationBar 绘图所需的内容。可以将 UINavigation 和其下的 UIBarButtonItem 视为容器,用于包含字符串,图片和其他的内容。

    1、navigationItem:

    我们都知道navigationItem是UIViewController的一个属性,这个属性是为UINavigationController服务的。文档中是这么解释的“The navigation item used to represent the view controller in a parent’s navigation bar. (read-only)”,即navigation item在navigation Bar代表一个viewController,具体一点儿来说就是每一个加到navigationController的viewController都会有一个对应的navigationItem,该对象由viewController以懒加载的方式创建,稍后我们可以在对象中堆navigationItem进行配置,可以设置leftBarButtonItem, rightBarButtonItem, backBarButtonItem, title以及prompt等属性。前三个每一个都是一个UIBarButtonItem对象,最后两个属性是一个NSString类型描述,注意添加该描述以后NavigationBar的高度会增加30,总的高度会变成74(不管当前方向是Portrait还是Landscape,此模式下navgationbar都使用高度44加上prompt30的方式进行显示)。当然如果觉得只是设置文字的title不够爽,你还可以通过titleview属性指定一个定制的titleview,这样你就可以随心所欲了,当然注意指定的titleview的frame大小,不要显示出界。

    例子:这段代码设置了navigationItem的rightBarButtonItem,同时设置了prompt信息。

    // set rightItem
    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithTitle:@"Root" style:UIBarButtonItemStyleBordered target:self action:@selector(popToRootVC)];
    childOne.navigationItem.rightBarButtonItem = rightItem;
    [rightItem release];
        
    // when you design a prompt for navigationbar, the hiehgt of navigationbar will becaome 74, ignore the orientation
    childOne.navigationItem.prompt = @"Hello, im the prompt";

    2、titleTextAttributes(ios5.0以后可用)

    这是UINavigationBar的一个属性,通过它你可以设置title部分的字体,这个属性定义如下:

    /* You may specify the font, text color, text shadow color, and text shadow offset for the title in the text attributes dictionary, using the keys found in UIStringDrawing.h.
     */
    @property(nonatomic,copy) NSDictionary *titleTextAttributes __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0) UI_APPEARANCE_SELECTOR;

    它的dictionary的key定义以及其对应的value类型如下:

    //    Keys for Text Attributes Dictionaries
    //    NSString *const UITextAttributeFont;                       value: UIFont
    //    NSString *const UITextAttributeTextColor;                 value: UIColor
    //    NSString *const UITextAttributeTextShadowColor;       value: UIColor
    //    NSString *const UITextAttributeTextShadowOffset;      value: NSValue wrapping a UIOffset struct.

    例子:这个例子就是设置title的字体颜色为黄色

    NSDictionary *dict = [NSDictionary dictionaryWithObject:[UIColor yellowColor] forKey:UITextAttributeTextColor];
    childOne.navigationController.navigationBar.titleTextAttributes = dict;

    3、wantsFullScreenLayout

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

    4、navigationBar中的stack

    这个属性可以算是UINavigationController的灵魂之一,它维护了一个和UINavigationController中viewControllers对应的navigationItem的stack,该stack用于负责navigationbar的刷新。“注意:如果navigationbar中navigationItem的stack和对应的NavigationController中viewController的stack是一一对应的关系,如果两个stack不同步就会抛出异常。

    抛出异常的例子:

    SvNavChildViewController *childOne = [[SvNavChildViewController alloc] initWithTitle:@"First" content:@"1"];
    [self.navigationController pushViewController:childOne animated:NO];
    [childOne release];
        
    // raise exception when the stack of navigationbar and navigationController was not correspond
    [self.navigationController.navigationBar popNavigationItemAnimated:NO];

    当pushViewcontroller的之后,强制把navigationBar中的navigationItem pop一个出去,程序立马挂起。

    5、navigationBar的刷新

    通过前面介绍的内容,我们知道navigationBar中包含了这几个重要组成部分:leftBarButtonItem, rightBarButtonItem, backBarButtonItem, title。当一个view controller添加到navigationController以后,navigationBar的显示遵循一下几个原则:

    1)Left side of the navigationBar

      a)如果当前的viewController设置了leftBarButtonItem,则显示当前VC所自带的leftBarButtonItem。

      b)如果当前的viewController没有设置leftBarButtonItem,且当前VC不是rootVC的时候,则显示前一层VC的backBarButtonItem。如果前一层的VC没有显示的指定backBarButtonItem的话,系统将会根据前一层VC的title属性自动生成一个back按钮,并显示出来。

      c)如果当前的viewController没有设置leftBarButtonItem,且当前VC已是rootVC的时候,左边将不显示任何东西。

      此处注意:5.0中新增加了一个属性leftItemsSupplementBackButton,通过指定该属性为YES,可以让leftBarButtonItem和backBarButtonItem同时显示,其中leftBarButtonItem显示在backBarButtonItem的右边。

    2)、title部分

      a)如果当前VC通过 .navigationItem.titleView指定了自定义的titleView,系统将会显示指定的titleView,此处要注意自定义titleView的高度不要超过navigationBar的高度,否则会显示出界。

      b)如果当前VC没有指定titleView,系统则会根据当前VC的title或者当前VC的navigationItem.title的内容创建一个UILabel并显示,其中如果指定了navigationItem.title的话,则优先显示navigationItem.title的内容。

    3)、Right side of the navigationBar

      a)如果当前VC指定了rightBarButtonItem的话,则显示指定的内容。

      b)如果当前VC没有指定rightBarButtonItem的话,则不显示任何东西。

     6、Toolbar

    navigationController自带了一个工具栏,通过设置 self.navigationController.toolbarHidden = NO来显示工具栏,工具栏中的内容可以通过viewController的toolbarItems来设置,显示的顺序和设置的NSArray中存放的顺序一致,其中每一个数据都一个UIBarButtonItem对象,可以使用系统提供的很多常用风格的对象,也可以根据需求进行自定义。

    设置Toolbar内容的例子:

    // test ToolBar
    UIBarButtonItem *one = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:nil action:nil];
    UIBarButtonItem *two = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemBookmarks target:nil action:nil];
    UIBarButtonItem *three = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:nil action:nil];
    UIBarButtonItem *four = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:nil action:nil];
    UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    [childOne setToolbarItems:[NSArray arrayWithObjects:flexItem, one, flexItem, two, flexItem, three, flexItem, four, flexItem, nil]];
    [one release];
    [two release];
    [three release];
    [four release];
    [flexItem release];
        
    childOne.navigationController.toolbarHidden = NO;

    7、UINavigationControllerDelegate

    当一个viewController要显示的时候通知一下外面,给你一个机会进行设置,包含如下两个函数:

    // Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack.
    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
    - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

    当你需要对某些将要显示的viewController进行修改的话,可实现该代理。

    8、UINavigationController的viewControllers属性

      通过该属性我们可以实现一次性替换整个navigationController的层次, 这个过程如果通过setViewControllers:animated:来设置,并指定动画为YES的画,动画将会从当前的navigationController所显示的vc跳转到所设置的目标viewController的最顶层的那个VC,而中间其他的VC将会被直接从VC层级中移除和添加进来(没有动画)。

     

    9、topViewController Vs visibleViewController

      topViewController代表当前navigation栈中最上层的VC,而visibleViewController代表当前可见的VC,它可能是topViewController,也可能是当前topViewController present出来的VC。因此UINavigationController的这两个属性通常情况下是一样,但也有可能不同。

      ------------------(完)

  • 相关阅读:
    2.Android之按钮Button和编辑框EditText学习
    《DSP using MATLAB》Problem 3.8
    《DSP using MATLAB》Problem 3.7
    《DSP using MATLAB》Problem 3.6
    《DSP using MATLAB》Problem 3.5
    《DSP using MATLAB》Problem 3.4
    《DSP using MATLAB》Problem 3.3
    《DSP using MATLAB》Problem 3.2
    《DSP using MATLAB》Problem 3.1
    《DSP using MATLAB》Problem 2.20
  • 原文地址:https://www.cnblogs.com/dayw/p/3275212.html
Copyright © 2011-2022 走看看