【iOS基础控件 - 15】- UINavigationController 多控制器 简单使用

A.概念

1.通常一个app有多个控制器

2.需要对这些控制器进行管理

3.有多个view的时候,用一个父view去管理多个子view

4.控制器管理也是如此,使用给一个父控制器,去控制子控制器

为了方便管理控制器,系统提供了两个控制器

  • UINavigationController
  • UITabBarController

B.UINavigationController的使用

UINavigationController的使用步骤
初始化UINavigationController
设置UIWindow的rootViewController为UINavigationController

根据具体情况,通过push方法添加对应个数的子控制器

 

1.初始化

2.设置为rootViewController

 1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 2     // 设置window
 3     self.window = [[UIWindow alloc] init];
 4     self.window.frame = [[UIScreen mainScreen] bounds];
 5     self.window.backgroundColor = [UIColor grayColor]; // window是灰色背景
 6     [self.window makeKeyAndVisible];
 7
 8
 9     // 设置UINavigationController
10     UINavigationController *nvController = [[UINavigationController alloc] init];
11     nvController.view.backgroundColor = [UIColor blueColor]; // 设置蓝色背景
12     self.window.rootViewController = nvController;
13
14     return YES;
15 }

3.通过push方法,增加子控制器

(1)创建3个控制器和绑定的xib文件

(2)一次push进navigationController的子控制器栈

 1     // 配置第一个子控制器
 2     ViewControllerOne *vc1 = [[ViewControllerOne alloc] init];
 3     [nvController pushViewController:vc1 animated:YES];
 4
 5     // 配置第二个子控制器
 6     ViewControllerTwo *vc2 = [[ViewControllerTwo alloc] init];
 7     [nvController pushViewController:vc2 animated:YES];
 8
 9     // 配置第三个子控制器,这是栈顶的控制器
10     ViewControllerThree *vc3 = [[ViewControllerThree alloc] init];
11     [nvController pushViewController:vc3 animated:YES];

(3)显示的是栈顶控制器的view

C.子控制器的管理原理

1.导航条在状态栏(高度20)下,高度44

1 - (void)applicationDidBecomeActive:(UIApplication *)application {
2     // 必须在加载完毕激活app后,所有的view的尺寸位置才能确定
3     UINavigationController *nvController = (UINavigationController *)self.window.rootViewController;
4     NSLog(@"%@", NSStringFromCGRect(nvController.view.frame)); // 整个导航控制器的frame
5     NSLog(@"%@", NSStringFromCGRect(nvController.navigationBar.frame)); // 导航条的frame
6 }
7  

out:

NavigationController[2669:183137] {{0, 0}, {320, 480}}

2014-12-19 21:16:30.413 NavigationController[2669:183137] {{0, 20}, {320, 44}}

2.UINavigationController有一个子控制器的栈,使用push方法就是往栈里面添加子控制器

1 @property(nonatomic,copy) NSArray *viewControllers; // The current view controller stack.

3.push子控制器的同时,替换window上的view,显示的总是栈顶控制器的view

1 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; // Uses a horizontal slide transition. Has no effect if the view controller is already in the stack.

 

D.子控制器栈的操作

1.栈和添加子控制器

(1)使用"pushViewController"

1     // 配置第一个子控制器
2     ViewControllerOne *vc1 = [[ViewControllerOne alloc] init];
3     [nvController pushViewController:vc1 animated:YES];

(2)使用 "addChildController"

  • UINavigationController中的”viewControllers"成员是一个数组,就是子控制器栈
  • "childViewControllers"的功能也是一样的(这是UIViewController的成员属性)
  • "addChildController"和"pushViewController"的功能一样(这是UIViewController的方法)

// 配置第一个子控制器

1     ViewControllerOne *vc1 = [[ViewControllerOne alloc] init];
2     [nvController addChildViewController:vc1];

(3)直接放入viewControllers数组

1     // 配置第一个子控制器
2     ViewControllerOne *vc1 = [[ViewControllerOne alloc] init];
3     nvController.viewControllers = @[vc1];

(4)初始化的时候指定rootViewController

1     // 传入一个viewController作为 nvController的 rootViewController
2     nvController = [[UINavigationController alloc] initWithRootViewController:vc1];

注意:不要混用"pushViewController"和"addChildViewController",有些情况会出现没有把控制器加入到栈。而且很混乱,完全不能预见结果。

(5)使用事件进行入栈

a.给第二个控制器的view加上两个按钮,分别跳向第三个和第四个控制器的view

b.点击事件方法

每个控制器都有一个navigationController属性,通知navigationController进行操作

 1 - (IBAction)goToThree {
 2     // 配置第三个子控制器
 3     ViewControllerThree *vc3 = [[ViewControllerThree alloc] init];
 4     [self.navigationController pushViewController:vc3 animated:YES];
 5 }
 6
 7 - (IBAction)gotoFour {
 8     // 配置第四个子控制器
 9     ViewControllerFour *vc4 = [[ViewControllerFour alloc] init];
10     [self.navigationController pushViewController:vc4 animated:YES];
11 }

2.主动出栈

(1)使用"popViewControllerAnimated:YES",弹出一个控制器

1 // 这里是第三个,要回到第二个
2 - (IBAction)backtoTwo {
3     [self.navigationController popViewControllerAnimated:YES];
4 }

(2)使用 "popToViewController" 弹出控制器,直到指定的控制器

(3)使用 "popToRootViewController" 弹出占内的控制器,直到rootViewController,回到栈底的控制器

1 // 现在是第三个控制器的view,要回到第一个控制器的view
2 - (IBAction)backtoOne {
3     // 其实这里拿不到第一个控制器vc1的引用
4 //    [self.navigationController popToViewController:vc1 animated:YES];
5
6     // 直接弹出,直到导航器的rootViewController,就是第一个子控制器vc1了
7     [self.navigationController popToRootViewControllerAnimated:YES];
8 }

E.设置导航条

1.导航条内容由栈顶控制器控制

2.使用navigationItem控制导航条内容

(1)标题title / titleView(这是UIViewController的成员属性)

1 @property(nonatomic,copy) NSString *title;  // Localized title for use by a parent controller.

sample:设置第一个控制器的title

1 - (void)viewDidLoad {
2     [super viewDidLoad];
3     self.navigationItem.title = @"第一个view";
4 }

(2)leftBarButtonItem / leftBarButtonItems,会覆盖“返回”按钮

(3)rightBarButtonItem / rightBarButtonItems

 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     self.navigationItem.title = @"第二个控制器";
 4
 5 //     设置左上角的item
 6     self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"我要回去" style:UIBarButtonItemStylePlain target:nil action:nil];
 7
 8     // 设置右上角的item
 9     // 使用bar按钮
10     UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:nil action:nil];
11
12     // 使用自定义view
13     UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithCustomView:[UIButton buttonWithType:UIButtonTypeContactAdd]];
14
15     // 这是这是从右到左排列显示
16     self.navigationItem.rightBarButtonItems = @[item1,item2];
17 }

注意: leftBarButtonItems 显示出来是按照数组顺序从左到右,而rightBarButtonItems是从右到左

例如把上面右边的items都放到左边:

self.navigationItem.leftBarButtonItems = @[item1, item2];

3.设置了上一级title之后,如果没有覆盖leftBarButtonItem(s),会自动使用上一级的title替换"返回"按钮的文字

-->左上角显示的文字是由上一级的控制器控制的

navigationItem.backBarButtonItem

1 // 第二个控制器
2 - (void)viewDidLoad {
3     [super viewDidLoad];
4      ...
5     // 设置第二个控制器的“返回”样式
6     self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"速速回2" style:UIBarButtonItemStylePlain target:nil action:nil];
7 }

4.navigatonBar就是整条导航条

nvController.navigationBar

当所有东西加载完毕之后,导航条的frame才能被初始化完毕

1 - (void)applicationDidBecomeActive:(UIApplication *)application {
2     // 必须在加载完毕激活app后,所有的view的尺寸位置才能确定
3     UINavigationController *nvController = (UINavigationController *)self.window.rootViewController;
4     NSLog(@"%@", NSStringFromCGRect(nvController.view.frame)); // 整个导航控制器的frame
5     NSLog(@"%@", NSStringFromCGRect(nvController.navigationBar.frame)); // 导航条的frame
6 }

out:

2014-12-19 23:12:51.049 NavigationController[4214:236071] {{0, 0}, {320, 480}}

2014-12-19 23:12:51.050 NavigationController[4214:236071] {{0, 20}, {320, 44}}

最后的点击链接图:

F.利用storyboard导航

1.创建一个基本的导航界面

(1)创建一个single view application,删除自带的ViewController类

(2)删除原来的ViewController,拖入一个NavigationController,并设置为Initial View Controller

(3)删除自带的rootViewController,拖入一个UIViewController

(4)设置新拖入的UIViewController为导航器的rootViewController

(5)设置UIView,这就是第一个页面

双击相应位置就可以编辑文字(例如title),但是使用storyboard方法不能拖入BarButtonItems组。

(6)拖入一个UIView到UIViewController,并且加入一些元素

运行效果:

2.创建跳转导航功能

(1)在第一个控制器的view中加入两个跳转按钮,拖入两个UIViewController

(2)拖曳指向,使用"push"事件

实现效果:这样在第一个控制器界面,就能跳转到第二个或者第三个控制器的界面了

注意:不要制造往回导航的按钮,其实是重新创建了一个控制器加入到控制器栈中

G.控制器的生命周期

1.生命周期方法

2.内存警告处理流程

当内存不够的时候,优先回收不存在屏幕上的view

所以应该在viewDidUnload方法中释放数据

时间: 2024-11-11 00:38:08

【iOS基础控件 - 15】- UINavigationController 多控制器 简单使用的相关文章

【iOS基础控件 15 - 2 】 UITabBarController 控制器管理

A.需求 1.类似QQ.微信顶部或者底部的窗口转换导航条 2.给每个页面添加相应内容 B.UITabBarController 1.基本概念: (1)内容高度 iOS7之前内容高度为:屏幕高度 - 状态栏高度44 - 底部导航条高度49 iOS7及之后,内容高度为整个屏幕 2.使用代码创建初始化 (1)创建一个UITabBarController UITabBarController的使用步骤 初始化UITabBarController 设置UIWindow的rootViewController

【iOS基础控件 -15 - 3 】Modal

A.概念 1.也可以用来切换控制器 2.如ActionSheet 除了push之外,还有另外一种控制器的切换方式,那就是Modal 任何控制器都能通过Modal的形式展示出来 Modal的默认效果:新控制器从屏幕的最底部往上钻,直到盖住之前的控制器为止 以Modal的形式展示控制器- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(vo

[iOS基础控件 6.11.1] - 控制器 & 控制器view

A.控制器的创建 控制器常见的创建方式有以下几种通过storyboard创建 直接创建 1 ViewController *vc = [[ViewController alloc] init]; xib设置了class后,当xib的文件名跟controller类名一样的时候,用这个方法默认就会加载xib中的controller 指定xib文件来创建 1 ViewController *vc = [[ViewController alloc] initWithNibName:@"ViewContr

iOS基础控件-UINavigationController 中的传值,代理传值,正向传值,反向传值

/* 程序过程: 1,创建一个根视图,一个二级视图 2,根视图 NavigationItem.title = Root  二级视图NavigationItem.title = Second 根视图NavigationItem.rightButton 入栈二级视图 3, 二级视图中创建三个按钮 按钮一  按钮二  按钮三 三个按钮点击时间都是出栈,并把自己的按钮的 titel 赋给 根视图的NavigationItem.title 4,当再次进入二级视图时,判断 根视图的NavigationIte

iOS基础控件UINavigationController中的传值

iOS基础控件UINavigationController中的传值,代理传值,正向传值,反向传值 #import <UIKit/UIKit.h> //声明一个协议 @protocol SendValue<NSObject> //定义一个方法 - (void)sendBtnTitle:(NSString *)title; @end @interface FirstViewController : UIViewController // 定义代理 @property (nonatomi

[iOS基础控件 - 5.5] 代理设计模式 (基于”APP列表&quot;练习)

A.概述 在"[iOS基础控件 - 4.4] APP列表 进一步封装,初见MVC模式”上进一步改进,给“下载”按钮加上效果.功能 1.按钮点击后,显示为“已下载”,并且不可以再按 2.在屏幕中间弹出一个消息框,通知消息“xx已经被安装”,慢慢消失 3.消息框样式为圆角半透明 B.不使用代理模式,使用app空间组和主View之间的父子View关系 1.在主View中创建一个消息框 主View控制器:ViewController.m 1 // 创建下载成功消息框 2 CGFloat labelWid

[iOS基础控件 - 6.10.2] PickerView 自定义row内容 国家选择Demo

A.需求 1.自定义一个UIView和xib,包含国家名和国旗显示 2.学习row的重用 B.实现步骤 1.准备plist文件和国旗图片 2.创建模型 1 // 2 // Flag.h 3 // CountriesSelection 4 // 5 // Created by hellovoidworld on 14/12/16. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import <Foun

[iOS基础控件 - 5.4] 广告分页代码(UIScrollView制作)

A.概念 例子就是桌面的APP列表,当APP数量超过一个屏幕,自动进行分页 B.实现思路 1.创建一个UIScrollView,这里设置为宽度跟屏幕相同,高度1/4屏幕高度左右 2.使用代码在UIScrollView中添加ImageView,横向放入多张ImageView 3.设置UIScrollView的contentSize为所有图片的宽度总和 4.要保证UIScrollView的宽度等于一张ImageView的宽度,才能正确分页 C.相关属性 设置属性pageEnable = YES,UI

ios基础控件之开关按钮(UISwitch)

UISwitch控件是iOS开发的基础控件,是非常简单的一个控件,因为它的方法比较少.UISwitch继承于UIControl基类,因此可以当成活动控件使用. 注意:开关状态通过它的on属性进行读取,该属性是一个BOOL属性 创建: UISwitch* mySwitch = [[ UISwitch alloc]initWithFrame:CGRectMake(0.150.0f,100.0f,0.0f,0.0f)]; 可能你会疑问为什么它的大小都设置为0?没错,它的大小你设置是无效的,系统会为你分