push入栈
pushViewController:animated: 这个方法使用需要一个视图控制器作为参数
pop 出栈
popViewControllerAnimated: 弹出栈顶视图控制器
popToViewController:animated: 弹出到指定视图控制器,一般需要配合ViewController属性(数组)使用。
popToRootViewControllerAnimated: 弹出到根视图控制器
注意:
1、出栈和入栈都要先找到navigationController
2、一个navagationController至少要有一个视图控制器,叫根视图控制器
属性:
1、ViewControllers //这是一个数组,数组中是所有栈中的视图控制器
2、topViewController //这是在栈顶位置视图控制器
3、visibleViewController //当前正在显示的视图控制器(未必是栈顶,以后会学到一种模式不入栈 但是可以显示)
4、navigationBar //导航条 可以设置
UINavigationController:
导航控制器,是iOS中最常⽤用的多视图控制器
之⼀一,它⽤用来管理多个视图控制器。
导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的
控制器。
UINavigationController继承于UIViewController,以栈的⽅方式管理所
控制的视图控制器,⾄至少要有⼀一个被管理的视图控制器,这个控制器
我们称作,导航控制器的根视图控制器。
任何继承⾃自UIViewController的类(多态)都可以作为根控制器。
工作原理:
UINavigationController通过栈的⽅方式管理控制器的切换,控制⼊入栈和出栈
来展⽰示各个视图控制器。 UINavigationController的ContentView⾥里始终显⽰示栈顶控制器的view。
viewControllers属性存储了栈中的所有被管理的控制器
navigationController属性,⽗父类中的属性,每个在栈中的控制器,都能通 过此属性,获取⾃自⼰己所在的UINavigationController对象。
实现页面间的跳转
UINavigationBar:
navigationBar—导航条,iOS7之后默认是透明的,iOS7之前默认是不
透明的。 navigationBar在透明情况,与contentView会重合⼀一部分区域。
navigationBar在不透明情况,contentView跟在navigationBar的下⾯面。 navigationBar竖屏下默认⾼高度44,横屏下默认⾼高度32.
UINavigationBar除了能定义⾃自⾝身的样式外,还管理⼀一组
UINavigationItem。 与UINavigationController相似,UINavigationBar也是以栈的⽅方式管
理⼀一组UINavigationItem。提供push和pop操作item。
每个视图控制器都有⼀一个navigationItem属性。navigationItem中设 置的左按钮、右按钮、标题等,会随着控制器的显⽰示,也显⽰示到 navigationBar上;
UINavigationItem:
UINavigationItem属于MVC中的M。封装了要显⽰示在UINavigationBar上
的数据。
UIBarButtonItem属于MVC的M。定义了UINavigationItem上按钮的触
发事件,外观等
-initWithBarButtonSystemItem:target:action:
-initWithTitle:style:target:action: -initWithImage:style:target:action: tintColor;
页面传值:
一种是属性传值;
一种是代理传值;
属性传值:如果从A页面往B页面传值,在B页面中声明属性,在A页面中跳转事件中给B页面的属性赋值;
从后一个页面返回前一个页面不会执行前面页面的loadView和viewDidLoad方法,而是执行viewWillAppear方法,因为,loadView和viewDidLoad方法的作用是将视图加载到内存,而从后一个页面返回时,前一个页面已经加载到内存,所以不用再次加载,所以不执行loadView和ViewDidLoad方法;
代理传值:
和代理设计模式一样,按照设置代理,遵循协议
// push是入栈的意思 pop是出栈的意思
// 能够显示的Controller视图是位于栈顶的Controller
[self.navigationController pushViewController:firstVC animated:YES];
// 出栈,一定是从栈顶出 返回上一级 最常用
[self.navigationController popViewControllerAnimated:YES];
// 弹出到指定ViewController
// 到指定ViewController之前的所有Controller全部出栈
[self.navigationController popToViewController:self.navigationController.viewControllers[0] animated:YES];
// 弹出到根视图控制器 返回首页
// 根视图控制器前的所有控制器全部出栈
[self.navigationController popToRootViewControllerAnimated:YES];
// 打印出navagationController栈中的所有的viewController
NSLog(@"%@",self.navigationController.viewControllers);
ViewController.m
#import "ViewController.h"
#import "SecondViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
//创建一个按钮,点击后进入子视图控制器,相当于进入子页面
UIButton *btn1=[UIButton buttonWithType:UIButtonTypeRoundedRect];
btn1.frame=CGRectMake(38, 100, 300, 30);
[btn1 setTitle:@"jump to secondviewcontroller" forState:UIControlStateNormal];
btn1.backgroundColor=[UIColor whiteColor];
self.view.backgroundColor=[UIColor redColor];
[btn1 addTarget:self action:@selector(jumpTo) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn1];
//设置导航条样式
//默认的时白色半透明(有点灰的感觉),UIBarStyleBlack,UIBarStyleBlackTranslucent,UIBarStyleBlackOpaque都是黑色半透明,其实它们有的时不透明有的时透明有的时半透明,但不知为何无效果
self.navigationController.navigationBar.barStyle=UIBarStyleDefault;
//设置导航条背景颜色,也是半透明玻璃状的颜色效果
self.navigationController.navigationBar.backgroundColor=[UIColor orangeColor];
//可以用self.navigationController.navigationBar.frame.size获得高宽,还有self.navigationController.navigationBar.frame.origin获得x和y
//高44,宽375,如果是Retina屏幕,那么宽和高@2x即可分别是750和88
//x是0很明显,y是20,其中上面20就是留给状态栏的高度
NSLog(@"%f",self.navigationController.navigationBar.frame.origin.y);
//隐藏导航条,由此点击进入其他视图时导航条也会被隐藏,默认是NO
//以下一个直接给navigationBarHidden赋值,一个调用方法,都是一样的,下面一个多了一个动画选项而已
self.navigationController.navigationBarHidden=NO;
[self.navigationController setNavigationBarHidden:NO animated:YES];
//给导航条增加背景图片,其中forBarMetrics有点类似于按钮的for state状态,即什么状态下显示
//UIBarMetricsDefault-竖屏横屏都有,横屏导航条变宽,则自动repeat图片
//UIBarMetricsCompact-竖屏没有,横屏有,相当于之前老iOS版本里地UIBarMetricsLandscapePhone
//UIBarMetricsCompactPrompt和UIBarMetricsDefaultPrompt暂时不知道用处,官方解释是Applicable only in bars with the prompt property, such as UINavigationBar and UISearchBar,以后遇到时再细说
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"big2.png"] forBarMetrics:UIBarMetricsDefault];
//如果图片太大会向上扩展侵占状态栏的位置,在状态栏下方显示
//clipsToBounds就是把多余的图片裁剪掉
self.navigationController.navigationBar.clipsToBounds=YES;
//设置导航标题
[self.navigationItem setTitle:@"主页"];
//设置导航标题视图,就是这一块可以加载任意一种视图
//视图的x和y无效,视图上下左右居中显示在标题的位置
UIView *textView1=[[UIView alloc]initWithFrame:CGRectMake(10, 10, 50, 30)];
textView1.backgroundColor=[UIColor whiteColor];
[self.navigationItem setTitleView:textView1];
//设置导航条的左右按钮
//先实例化创建一个UIBarButtonItem,然后把这个按钮赋值给self.navigationItem.leftBarButtonItem即可
//初始化文字的按钮类型有UIBarButtonItemStylePlain和UIBarButtonItemStyleDone两种类型,区别貌似不大
UIBarButtonItem *barBtn1=[[UIBarButtonItem alloc]initWithTitle:@"左边" style:UIBarButtonItemStylePlain target:self action:@selector(changeColor)];
self.navigationItem.leftBarButtonItem=barBtn1;
//我们还可以在左边和右边加不止一个按钮,,且可以添加任意视图,以右边为例
//添加多个其实就是rightBarButtonItems属性,注意还有一个rightBarButtonItem,前者是赋予一个UIBarButtonItem对象数组,所以可以显示多个。后者被赋值一个UIBarButtonItem对象,所以只能显示一个
//显示顺序,左边:按数组顺序从左向右;右边:按数组顺序从右向左
//可以初始化成系统自带的一些barButton,比如UIBarButtonSystemItemCamera是摄像机,还有Done,Reply等等,会显示成一个icon图标
//还可以initWithImage初始化成图片
//还可以自定义,可以是任意一个UIView
UIBarButtonItem *barBtn2=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(changeColor2)];
UIBarButtonItem *barBtn3=[[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"logo-40@2x.png"] style:UIBarButtonItemStylePlain target:self action:@selector(changeColor3)];
UIView *view4=[[UIView alloc]initWithFrame:CGRectMake(10, 10, 20, 20)];
view4.backgroundColor=[UIColor blackColor];
UIBarButtonItem *barBtn4=[[UIBarButtonItem alloc]initWithCustomView:view4];
NSArray *arr1=[[NSArray alloc]initWithObjects:barBtn2,barBtn3,barBtn4, nil];
self.navigationItem.rightBarButtonItems=arr1;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)changeColor{
self.view.backgroundColor=[UIColor purpleColor];
}
-(void)changeColor2{
self.view.backgroundColor=[UIColor whiteColor];
}
-(void)changeColor3{
self.view.backgroundColor=[UIColor orangeColor];
}
-(void)jumpTo{
//这里面核心的有两个,所谓跳转,其实就是往导航控制器栈中PUSH或者POP一个视图控制器,这样在最上面的视图控制器就变了,这样视图也跟着变了,因为只显示在栈顶得那个视图控制器的视图
//所以(1)控制所谓的跳转,其实是导航控制器在控制,在里面的元素都可以通过navigationController属性获取到它们所在的导航控制器
//所以(2)获取到导航控制器之后,使用Push的那个方法,往栈里面放一个视图控制器senCon1,这个新放入的在栈顶,就显示它的视图,所以用户改变页面跳转了
SecondViewController *senCon1=[[SecondViewController alloc]init];
[self.navigationController pushViewController:senCon1 animated:YES];
}
@end
SecondViewControllor.m
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad {
UILabel *label1=[[UILabel alloc]init];
label1.frame=CGRectMake(38, 80, 300, 30);
label1.backgroundColor=[UIColor whiteColor];
label1.text=@"This is secondviewcontroller";
[self.view addSubview:label1];
UIButton *btn2=[UIButton buttonWithType:UIButtonTypeRoundedRect];
btn2.frame=CGRectMake(38, 120, 300, 30);
[btn2 setTitle:@"backTo" forState:UIControlStateNormal];
btn2.backgroundColor=[UIColor orangeColor];
[self.view addSubview:btn2];
[btn2 addTarget:self action:@selector(backTo) forControlEvents:UIControlEventTouchUpInside];
//设置导航标题,这个时候的返回按钮的title就是上一级的navigationItem的title文字
[self.navigationItem setTitle:@"子页"];
//我们也可以在子页中自定义一个返回按钮覆盖原先的"<back"
UIBarButtonItem *barBtn5=[[UIBarButtonItem alloc]initWithTitle:@"回家" style:UIBarButtonItemStylePlain target:self action:@selector(backTo)];
self.navigationItem.leftBarButtonItem=barBtn5;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)backTo{
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
}
@end