导航视图控制器是一个特殊的容器视图控制器,它可以维护有明确层次关系的视图之间的切换。我们可以打开模拟器或者你的 iPhone 看看设置功能,这里就是一个典型的对导航视图控制器的应用,如下图所示。很明显,导航视图控制器维护了一个栈结构,这是一种先进后出(FILO)的结构,我们将一个一个的视图压入栈中,当我们想返回的时候就可以依次出栈。
可以通过 UINavigationController 的 viewControllers 属性获得其栈中保存的所有视图控制器;topViewController 可以获得栈顶的视图控制器。
一个导航视图控制器通常是由以下几个部分构成的:
导航视图控制器会维持一个导航条 (UINavigationBar),这个导航条被所有的视图控制器共享,可以通过 UINavigationController 对象 navigationBar 属性获得导航条,再通过下面的属性设置其半透明效果,注意对导航条的设置将对所有的视图控制器生效。
说明:UIBarPostion 和 UIBarMetrics 都是枚举类型,前者表示导航栏的位置;后者表示导航栏的外观。前者可能的取值包括:UIBarPositionAny(不指定位置)、UIBarPositionBottom(位于视图底部)、UIBarPositionTop(位于视图顶部) 和 UIBarPositionTopAttached(位于屏幕顶部同时也在其视图的顶部);后者可能的取值包括:UIBarMetricsDefault(设备默认的外观)、UIBarMetricsCompact(手机尺寸的外观) 等。
通过视图控制器的 navigationItem 属性可以获得和视图控制器对应的导航栏项,该属性是只读的,但是通过它的子属性可以对 UINavigationItem 进行定制。可以定制的内容包括:
说明:由于 navigationItem 是每个视图持有自己的 navigationItem,因此可以为每个视图定制不同的导航项。
如果当前视图控制器通过 navigationItem 设置了 leftBarButtonItem,则显示当前视图控制器设置好的 leftBarButtonItem;如果当前视图控制器没有设置 leftBarButtonItem,且当前视图控制器不是根视图控制器,显示上一层的 backBarButtonItem;如果上一层没有指定 backBarButtonItem,系统将根据上一层视图控制器的标题自动生成一个返回按钮;如果当前视图控制器没有设置 leftBarButtonItem 且当前视图控制器是根视图控制器,则左边不显示任何东西。
如果当前视图控制器通过 navigationItem 属性定制了 titleView,那么将会显示自定义的 titleView,titleView 的高度不应该超过导航条的高度;如果当前视图控制器没有定制 titleView,系统会根据当前视图控制器的标题或者 navigationItem 的标题创建一个 UILabel 来显示此标题;navigationItem 的标题优于视图控制器的标题。
强调:UINavigationController 本身并不显示无需定制,UINavigationBar 属于导航控制器 (子对象),它使被多个视图共享的,当你切换视图控制器时,导航栏并没有切换,如果需要定制导航视图控制器就需要定制导航栏以及导航栏上的项目 UINavigationItem。我们可以让每个视图控制器都有自己的 UINavigationItem,并按照自己的意愿来创建它。
下面通过代码对上述内容加以展示。
- // 重设rightBarButtonItem
- self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage: image style: UIBarButtonItemStyleDone target: self action: @selector(onClick: )];
- //重设leftBarButtonItem
- self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage: [UIImage imageNamed: @"itemImage1"] landscapeImagePhone: [UIImage imageNamed: @"itemImage2"] style: UIBarButtonItemStyleBordered target: nil action: nil];
- UIBarButtonItem * item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemCompose target: nil action: nil];
- UIBarButtonItem * item2 = [[UIBarButtonItem alloc] initWithTitle: @"OK"style: UIBarButtonItemStylePlain target: nil action: nil];
- // 使用自定义视图,创建barButtonItem
- UISwitch * sw = [[UISwitch alloc] initWithFrame: CGRectMake(0, 0, 20, 20)]; [sw addTarget: self action: @selector(pushNextViewController) forControlEvents: UIControlEventValueChanged];
- // barButton官方推荐大小是20*20
- UIBarButtonItem * item3 = [[UIBarButtonItem alloc] initWithCustomView: sw];
- // 将多个item添加到右侧
- self.navigationItem.rightBarButtonItems = @ [item1, item2, item3];
- UIButton * goBackButton = [UIButton buttonWithType: UIButtonTypeSystem];
- goBackButton.frame = CGRectMake(10, 10, 60, 40); [goBackButton addTarget: self action: @selector(goBackButtonClicked) forControlEvents: UIControlEventTouchUpInside]; [goBackButton setTitle: @"滚蛋"forState: UIControlStateNormal];
- UIBarButtonItem * barItem = [[UIBarButtonItem alloc] initWithCustomView: goBackButton];
- self.navigationItem.leftBarButtonItem = barItem;
每个导航控制器,还配备了工具条 (44 坐标高),默认隐藏,可以通过将导航视图控制器的 toolBarHidden 属性设置为 NO 使其显示。工具条属于 UINavigationController,一个导航控制器,只有一个工具条。工具条上的 toolBarItem 属于每个视图控制器,每个视图控制器可以单独定制工具条上的每个项。
- self.navigationController.toolbarHidden = NO;
- UIImage * bgImage = [UIImage imageNamed: @"toolBar"]; [navigationController.toolbar setBackgroundImage: bgImage forToolbarPosition: UIBarPositionBottom barMetrics: UIBarMetricsDefault]; [self.navigationController.toolbar setTintColor: [UIColor whiteColor]];
- UIBarButtonItem * item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAction target: nil action: nil];
- UIBarButtonItem * item2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemBookmarks target: nil action: nil];
- UIBarButtonItem * item3 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemCamera target: nil action: nil];
- UIBarButtonItem * spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFlexibleSpace target: nil action: nil];
- self.toolbarItems = @ [item1, spaceItem, item2, spaceItem, item3];
从 iOS 5 开始,UIKit 中提供了一个叫做 UIAppearance 的协议,通过该协议可以轻松的统一你的界面,它提供如下两个方法:
- [[UIBarButtonItem appearanceWhenContainedIn: [UINavigationBar class], nil] setBackgroundImage: myNavBarButtonBackgroundImage forState: state barMetrics: metrics]; [[UIBarButtonItem appearanceWhenContainedIn: [UINavigationBar class], [UIPopoverController class], nil] setBackgroundImage: myPopoverNavBarButtonBackgroundImage forState: state barMetrics: metrics]; [[UIBarButtonItem appearanceWhenContainedIn: [UIToolbar class], nil] setBackgroundImage: myToolbarButtonBackgroundImage forState: state barMetrics: metrics]; [[UIBarButtonItem appearanceWhenContainedIn: [UIToolbar class], [UIPopoverController class], nil] setBackgroundImage: myPopoverToolbarButtonBackgroundImage forState: state barMetrics: metrics];
来源: http://lib.csdn.net/article/ios/42154