导航视图控制器基本概念和用法

1.导航视图控制器的基本概念 

·导航视图控制器的基本概念
·导航视图控制器(UINavigationController)是用于构建分层应用程序的主要工 具,管理着多个内容视图的换入(压入)和换出(弹出)。自身提供了视图切换的动画 效果。
·它的父类是UIViewController,是所有视图控制器的基类(如下图所示)。 ·导航控制器是以栈的形式来实现。



栈的概念与性质

·栈的基本概念和性质
   栈是一种数据结构,采用一种先进后出(后进先出)的原则。如,我们把衣服一件一件放到箱子中,就可以看成是一个对象入栈的过程。当需要拿到最底层的衣服,需要把盖在上层的衣服一层一层拿掉,即后进先出的原则。同理,导航控制器也是以栈的形式来管理视图控制器,任何视图控制器都可以放入栈中。 
·向栈中添加一个对象的操作称为入栈(push),即把对象推入到了栈里。
·我们把第一个入栈的对象,叫做基栈。 
·我们把第最后一个入栈的对象,叫做栈顶。 
·我们在栈中删除一个对象的操作叫做出栈(pop)。 
·当前显示的视图控制器,即为栈顶。选择“返回”时,这个视图控制器就出栈了。


导航控制器的基本样式

·基本样式
蓝色部分为:导航控制器的导航栏(NavigationBar);
橙色部分为:控制器包 含的内容视图(用户感兴趣的区域);
绿色部分为:导航控制器的工具栏 (UIToolBar),默认是隐藏的;
这些视图共同构成了导航控制器。



导航控制器的结构图



导航控制器中视图元素尺寸



实现导航控制器

一个简单的导航控制器

// 控制器的初始化,为控制器添加导航控制器
RootViewController *rootVC = [[RootViewController alloc] init]; UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:rootVC];
// 子控制器设置title,显示在导航栏上的标题
self.title = @"根控制器";
// 控制器之间的导航
SecondViewController *secondVC = [[SecondViewController alloc] init]; [self.navigationController pushViewController:secondVC animated:YES]; [secondVC release];
// 隐藏(显示) 导航栏、工具栏目
[self.navigationController setNavigationBarHidden:NO animated:YES]; [self.navigationController setToolbarHidden:NO animated:YES];
// 延迟调用hidden方法,第二个参数是可以传递一个对象
[self performSelector:@selector(hidden) withObject:nil afterDelay:0.3];

2、导航控制器常用属性与常用方法

·导航控制器常用属性

// 获取到在栈中最顶层的视图控制器
@property(nonatomic,readonly,retain) UIViewController *topViewController;


// 获取到在栈中当前显示的视图控制器
@property(nonatomic,readonly,retain) UIViewController *visibleViewController;


// 在栈中当前视图控制器
@property(nonatomic,copy) NSArray *viewControllers;


// 隐藏导航栏,默认是不隐藏,NO
@property(nonatomic,getter=isNavigationBarHidden) BOOL navigationBarHidden;


// 获取到导航栏目
@property(nonatomic,readonly) UINavigationBar *navigationBar;


·常用方法

// 初始化一个根视图控制器,在栈的最底层
- (id)initWithRootViewController:(UIViewController *)rootViewController;


// 压入到一个新的视图控制器中,在栈中最顶层,可以选择是否需要动画效果
- (void)pushViewController:(UIViewController *)viewController animated: (BOOL)animated;


// 弹出一个视图控制器,可以选择是否需要动画效果
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;


// 弹出到指定的视图控制器中,可以选择是否需要动画效果
- (NSArray *)popToViewController:(UIViewController *)viewController animated: (BOOL)animated;


// 回到根视图控制器,可以选择是否需要动画效果
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;


导航控制器的层次关系



3 、 UINavigationBar

·导航栏的基本概念
一个导航控制器一般包含有四个对象:UINavigationController、 UINavigationBar、UIViewController、UINavigationItem;其中 NavigationItem存放在UINavigationBar上。由下图我们可以看出一个导航控制 器含有多个视图控制器,一个视图控制器控制器一个UINavigationItem。



·导航栏结构剖析图 (类关系图)



导航栏结构图



定制导航栏

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

UIView *cView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 160, 44)]; cView = [UIColor redColor];
self.navigationItem.titleView = cView; // self 视图控制器
[cView release]; // 自定义一个视图

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


·定制左、右栏目常用方法
UIBarButtonItem类提供了常用的四个初始化方法,通过这些不同的初始化方 法,用户可以得到不同风格的Item。如,可以调用系统的定义的Item,也可以调 用用户自定义的Item(图片、标题),用户还可以自定义一个视图。

// 初始化一个UIBarButtonItem 的实例,初始化一个系统的Item
- (id)initWithBarButtonSystemItem:(UIBarButtonSystemItem)systemItem target:(id)target action:(SEL)action;
// 初始化一个带图片的UIBarbuttonItem
- (id)initWithImage:(UIImage *)image style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action;
// 初始化一个只带标题的UIBarButtonItem实例
- (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action;
// 初始化自定义的一个视图
- (id)initWithCustomView:(UIView *)customView;


设置导航栏

·设置风格

// 设置导航栏的风格为黑色
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
// 设置导航栏为透明
self.navigationController.navigationBar.translucent = YES;


·设置颜色

// 设置导航栏的颜色
self.navigationController.navigationBar.tintColor = [UIColor redColor];
// 设置自定义颜色,注意每个颜色的值范围是0-1之间。最后一个参数是设置透明度
[UIColor colorWithRed:0/255.0 green:125/255.0 blue:122/255.0 alpha:1];
// 以图片作为颜色,注意这里是无法设置NavigationBar
[UIColor colorWithPatternImage:[UIImage imageNamed:@"img.png"]];


·隐藏返回按钮

// 隐藏返回按钮,后者带动画效果

[self.navigationItem setHidesBackButton:YES];

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


·设置prompt属性

导航栏的prompt属性,通过navigationItem来设置,其主要作用是用于提示用 户。比如,用户正在请求网络数据时,提示用户数据正在加载。待加载完成后可以 将它的值设置为nil,取消显示。

// 设置导航栏提示用户的内容
self.navigationItem.prompt=@"加载数据";
// 取消提示
// 设置导航栏提示用户的内容
self.navigationItem.prompt=nil;




4、导航控制器中的工具栏

·创建UIToolBar的实例

UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0,460-88, 320, 44)];

// 初始化UIToolBar的 UIBarButtonItem实例,与UINavigationItem 中左、右栏目相同的
UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithTitle:@"天气" style:UIBarButtonItemStyleBordered target:self action:nil];

// 向UIToolBar添加UIBarButtonItem
NSArray *itemsArray = [NSArray arrayWithObjects:item1, nil]; [self setToolbarItems:itemsArray animated:YES];

    // 如何设置UIToolbar的间隔。前者是item之间选择一个合适的列宽,后者用户可以自定义item之间的列宽。需要通过UIBarButtonItem的实例的width属性来设置。
    UIBarButtonSystemItemFlexibleSpace | UIBarButtonSystemItemFixedSpace

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

// 显示导航控制器
[self.navigationController setToolbarHidden:NO animated:YES];

这里我们需要注意,与UINavigationBar类似,导航控制器拥有只拥有一个 UIToolBar实例,但UIToolBar所拥有的UIBarButtonItem实例,是由视图控制器 管理的。如下代码所示:

// 将UIBarButtonItem放入数组中,最后添加至UIToolBar中,self表示视图控制器
[self setToolbarItems:itemsArray animated:YES];
// 以下代码UIBarButtonItem不会出现在UIToolBar中,且toolbar是只读属性
[self.navigationController.toolbar setItems:itemsArray animated:YES];

5、导航控制器的委托方法

·设置代理方法
·导航控制器的委托方法UINavigationControllerDelegate,通过设置代理监听视图 控制器的切换。

self.navigationController.delegate = self; //设置代理方法

// 视图控制器将要显示时调用
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
// 视图控制器已经显示时调用
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated

6、自定义导航栏

我们知道导航栏的背景颜色可以通过“tintColor”来设置。如果需要设置背景, 则需要通过类别修改drawRect方法。5.0以上的SDK提供了设置背景图片的方 法,这里我们需要注意版本兼容性的问题。

//  5.0 之前,类别扩展给 UINavigationBar 设定图片背景
@implementation UINavigationBar (CustomNavigationBar) 
- (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"image.png"];
    [image drawInRect:rect];
}
@end

// 5.x 新增了 setBackgroundImage 方法来设置背景图片
 UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:viewController];
[navigation.navigationBar setBackgroundImage:[UIImage imageNamed:@"image.png"] forBarMetrics:UIBarMetricsDefault];

导航控制器小结

·小结
·一个UINavigationController对应一个NavigationBar实例 
·一个UINavigationController可以包含多个UIViewController 
·每一个UIViewController对应一个UINavigationItem实例 
·UINavigationItem控制器多个UIBarButtonItem(2个) 
·一个UINavigationController控制着一个UIToolBar实例
·UIToolBar中的UIBarButtonItem由当前的视图控制器管理,而不是由导航控制器 控制。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章