基本概念:导航视图控制器(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 appearance] setBarTintColor:[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
-------我是快乐的小尾巴`(*∩_∩*)′)