iOS学习26之UINavigationController
1. UINavigationController
1> 概述
UINavigationController : 导航控制器, 是 iOS 中最常用的多视图控制器之一, 用它来管理多个视图控制器
导航控制器可以称之为是 : 管理控制器的控制器, 主要管理有层次递进关系的控制器
2> 创建
UINavigationController 继承与 UIController , 以栈的方式管理所控制的视图控制器, 至少要有一个被管理的控制器, 这个控制器我们称作 : 导航控制器的根视图控制器
任何继承自 UIController 的类(多态)都可以作为根控制器
1 // 1.创建window对象并设置为屏幕大小 2 self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 3 4 // 2.设置window的背景颜色 5 self.window.backgroundColor = [UIColor whiteColor]; 6 // 3.显示window 7 [self.window makeKeyAndVisible]; 8 9 // 4.设置根视图控制器 10 11 // 设置导航控制器(第一个入栈的控制器,也就是第一个显示的控制器) 12 UINavigationController *rootNav = [[UINavigationController alloc] initWithRootViewController:[[RootViewController alloc] init]]; 13 14 self.window.rootViewController = rootNav;
2. UINavigationBar
1> 概述
UINavigationBar (导航栏)上的设置主要分两部分, 一为导航栏上的各种导航部件(UINavigationItem) , 二为导航栏自身(UINavigationBar)的相关设置。
navigationBar —导航条, iOS7之后默认是半透明的, iOS7之前默认是不透明的。
当半透明效果开启时,self.view以屏幕左上角为坐标原点; 关闭时,以导航条左下角为坐标原点
self.navigationController.navigationBar.translucent = NO;
navigationBar 竖屏下默认高度 44, 横屏下默认高度 32。
iOS7之后, navigationBar 的背景会延伸到 statusBar 上。导航栏高度仍保持 44,但显示效果为 64。
每个视图控制器都有一个 navigationItem 属性。navigationItem 中设置的左按钮、右按钮、标题等, 会随着控制器的显示,也显示到 navigationBar 上。
2> 常用的属性
① UINavigationBar 的属性
1 // 导航控制器的显隐属性 YES是隐藏, NO为显示 2 self.navigationController.navigationBarHidden = NO; 3 4 // NavigationBar (导航条) 5 // 设置导航条是否开启半透明效果(iOS7.0之后,默认是开启的) 6 // 当半透明效果开启时,self.view以屏幕左上角为坐标原点; 关闭时,以导航条左下角为坐标原点 7 self.navigationController.navigationBar.translucent = NO; 8 9 // UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, kWidth, 44)]; 10 // 11 // myView.backgroundColor = [UIColor redColor]; 12 // 13 // [self.view addSubview:myView]; 14 15 // 修改导航条的颜色 16 self.navigationController.navigationBar.barTintColor = [UIColor blackColor]; 17 18 // 设置导航元素的颜色 19 self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; 20 21 // 导航栏的样式 22 self.navigationController.navigationBar.barStyle = UIBarStyleBlack; 23 24 // 设置导航条标题 25 self.title = @"根视图";
② navigationItem 的属性
1 // navigationItem 属性 用于设置子控件 2 self.navigationItem.title = @"根视图"; 3 4 // 左按钮 5 // self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(leftButtonAction:)]; 6 7 self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(leftButtonAction:)]; 8 9 // 右按钮 10 self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"前进" style:UIBarButtonItemStylePlain target:self action:@selector(rightButtonAction:)]; 11 12 // self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(rightButtonAction:)]; 13 14 // self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"next"] style:UIBarButtonItemStylePlain target:self action:@selector(rightButtonAction:)];
③ UIBarButtonItem 初始化方法总结
具体实现方法见上面的代码
③ 左右 Item 数组
1 UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:@selector(rightButtonAction:)]; 2 3 UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:@selector(rightButtonAction:)]; 4 5 // 右按钮数组 6 self.navigationItem.rightBarButtonItems = @[item1, item2];
④ TitleView 标题视图
1 // 标题视图 2 UISegmentedControl *segment = [[UISegmentedControl alloc] initWithItems:@[@"nan", @"nv", @"-1"]]; 3 4 segment.frame = CGRectMake(0, 0, 180, 30); 5 6 segment.selectedSegmentIndex = 0; 7 // 将分组添加到标题视图上 8 self.navigationItem.titleView = segment;
3. 页面跳转
1> 工作原理
UINavigationController 通过栈的方式管理控制器的切换,控制入栈和出栈来展示各个视图控制器
UINavigationController 的 ContentView 里始终显示栈顶控制器的 view
viewControllers 属性是一个可变数组(NSMutableArray)存储了栈中的所有被管理的控制器,入栈的时候,使用 addObject 把新的视图控制器对象添加到数组的末尾,出栈时 removeLastObject 移除数组末尾的视图控制器对象
self.navigationController.viewControllers[0] // 实现方法
navigationController 属性,父类中的属性,每个在栈中控制器,都能通过此属性,获取自己所在的 UINavigationController 对象
2> 常用属性
3> 入栈和出栈方法
1 // 跳到第一页,使用压栈的方法 2 [self.navigationController pushViewController:firstVC animated:YES]; 3 4 // pop 掉最上面的 ViewController 5 [self.navigationController popViewControllerAnimated:YES]; 6 7 // pop 掉 viewControllers 数组中对应的 viewController上的视图, 可以跳到任意一个 viewController 8 // viewControllers 所有处于栈中的控制器,使用数组保存 9 [self.navigationController popToViewController:self.navigationController.viewControllers[0] animated:YES]; 10 11 // 将除了RootViewController之外的所有Controller从栈区pop 12 [self.navigationController popToRootViewControllerAnimated:YES];
4> 进入下一页
1 // 按钮的点击事件 2 [pushBtn addTarget:self action:@selector(pushBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 3 (viewDidLoad方法中) 4 5 6 // 点击事件实现 7 - (void)pushBtnClick:(UIBarButtonItem *)sender 8 { 9 // 创建要跳转到的界面的对象 10 SecondViewController *secondVC = [[SecondViewController alloc] init]; 11 12 // 使用push跳转到下一页 13 [self.navigationController pushViewController:secondVC animated:YES]; 14 }
5> 返回上一页
1 // 按钮点击事件 2 [popBtn addTarget:self action:@selector(popBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 3 (viewDidLoad方法中) 4 5 - (void)popBtnClick:(UIBarButtonItem *)sender 6 { 7 // pop到上一页 8 [self.navigationController popViewControllerAnimated:YES]; 9 }
具体跳转到哪一页,根据你自己的需求使用 3> 中的方法实现
4.模态
1> 模态进入下一页
1 // 点击事件的实现 2 - (void)showBtnClick:(UIButton *)sender 3 { 4 // 创建要跳转的页面 5 ShowViewController *showVC = [[ShowViewController alloc] init]; 6 7 // 以要跳转的页面为根视图控制器创建导航控制器 8 UINavigationController *showNAV = [[UINavigationController alloc] initWithRootViewController:showVC]; 9 10 // UIModalTransitionStylePartialCurl 翻页方式 推出 11 // UIModalTransitionStyleFlipHorizontal 水平旋转方式 推出 12 // UIModalTransitionStyleCrossDissolve 交叉叠化溶解方式 推出 13 // UIModalTransitionStyleCoverVertical 垂直覆盖方式 推出 14 15 // 设置模态的样式(只有上述的4种,如果有需要可以自己编写) 16 showVC.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 17 // 模态跳转到下一页 18 [self presentViewController:showNAV animated:YES completion:nil]; 19 }
模态不是通过压栈的方式进行页面跳转, 因此在跳转页面时, 需要重新创建导航控制器
2> 模态返回上一页
1 // 按钮点击事件 2 - (void)goBackBtnClick:(UIButton *)sender 3 { 4 // 模态返回到上一页 5 [self dismissViewControllerAnimated:YES completion:nil]; 6 }
3> 页面切换方式对比
页面的切换方式主要分为: 推出(push) 和 模态(present)
推出(push) 用于一系列的视图之间的跳转, 有层次递进关系
模态(present) 用于单独功能之间的跳转和主要业务逻辑没有关联(登录, 歌曲播放页, 系统相册, 应用中调用系统功能)