前言

控制器管理(控制器之间的切换)

  1. 控制器、view的多种创建方式
  2. UINavigationController 的简单使用(添加、移除子控制器)
  3. UINavigationBar内容的设置
  4. 控制器的生命周期

I 控制器常见的创建方式

1.1 通过storyboard创建

  1. 先加载storyboard文件(Test是storyboard的文件名)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Test" bundle:nil];
  1. 接着初始化storyboard中的控制器
HMViewController *HM = [storyboard instantiateInitialViewController];//初始化“初始控制器”(箭头所指的控制器)
//通过一个标识初始化对应的控制器
HMViewController *HM = [storyboard instantiateViewControllerWithIdentifier:@”HM"];

1.2 直接创建

HMViewController *hm = [[HMViewController alloc] init];

1.3 指定xib文件来创建

- (void) settingsetRootViewControllerFromXib{
// [self.window setRootViewController:[[HSPurpleViewController alloc]initWithNibName:@"HSPurpleView" bundle:nil]];
/** 如果没有指定xib,就会默认查找HSPurpleView(没有Controller之前的字符串HSPurpleView的xib,接着会查找HSPurpleViewController的xib) ,如果都没找到对应的xib描述文件,系统就自己创建一个View对象进行展示*/
[self.window setRootViewController:[[HSPurpleViewController alloc]init]];
}

ps:指定xib文件的fileOwner,以及控制器的View (在xib 界面进行操作)

<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="HSPurpleViewController">
<connections>
<outlet property="view" destination="iN0-l3-epB" id="fkF-S7-TYo"/>
</connections>
</placeholder>

II 创建ViewController的view


iOS小技能:导航控制器(控制器、view的多种创建方式、控制器的生命周期)_加载

p s:父类的loadView 会自动完成上图的右侧逻辑

/** 自定义View  custom view */
#if
- (void)loadView{ // This is where subclasses should create their custom view hierarchy if they aren't using a nib. Should never be called directly.
// [super loadView];//父类的loadView 会自动完成上图的右侧逻辑
//实例化View
self.view = [[UITableView alloc]init];
[self.view setBackgroundColor:[UIColor lightGrayColor]];
NSLog(@"%s",__func__);
}
#endif

iOS小技能:导航控制器(控制器、view的多种创建方式、控制器的生命周期)_生命周期_02

2.1 控制器的view是延迟加载的即懒加载

直到第一次访问view属性时,才会去加载或者创建UIViewController的视图集。

//window要显示到屏幕,必须设置它为主窗口,并且设置为可见
[self.window makeKeyAndVisible];//Makes the receiver the key window and visible.--这个时候会调用控制器的loadView 方法

1》可以用isViewLoaded方法判断一个UIViewController的view是否已经被加载

2》控制器的view加载完毕就会调用viewDidLoad方法

2.2 内存警告处理:

iOS小技能:导航控制器(控制器、view的多种创建方式、控制器的生命周期)_加载_03

2.3 生命周期方法

iOS小技能:导航控制器(控制器、view的多种创建方式、控制器的生命周期)_生命周期_04

众所周知,每一个UIViewController管理着一个由多个视图组成的树形结构,其中根视图保存在UIViewController的view属性中。UIViewController会懒加载它所管理的视图集,直到第一次访问view属性时,才会去加载或者创建UIViewController的视图集。

  • 几种常用的加载或者创建UIViewController的视图集的方法如下。 ·使用Storyboard。 ·使用Nib文件。 ·使用代码,即重写-​​loadView​​。

以上这些方法最终都会创建出合适的根视图并保存在UIViewController的view属性中,这是UIViewController生命周期的第一步。当UIViewController的根视图需要展示在页面上时,​​会调用-viewDidLoad方法。在这个方法中,我们可以做一些对象初始化相关的工作。​

当UIViewController的视图在屏幕上的显示状态发生变化时,UIViewController会自动回调一些方法,以确保子类能够应对这些变化。

iOS小技能:导航控制器(控制器、view的多种创建方式、控制器的生命周期)_iOS_05

UIViewController被销毁前,还会回调-dealloc方法。我们一般通过重写该方法来主动释放不能被ARC自动释放的资源。

​当执行到-viewDidAppear:方法时,表示视图已经在屏幕上渲染完成,即页面已经显示出来,正等待用户进行下一步操作。因此,执行到-viewDidAppear:方法的时间点是触发页面浏览事件的最佳时机。如果想要实现页面浏览事件的全埋点,​​​就需要使用iOS的“黑魔法”——Method Swizzling的相关技术

​ viewDidLoad的调用顺序​​:

需要注意的是,此时,视图的bounds还没有确定。

  • 如果使用代码创建视图集,-viewDidLoad方法会在-loadView方法调用结束之后运行。
  • 如果使用Stroyboard或者Nib文件创建视图集,-viewDidLoad方法则会在-awakeFromNib方法之后调用。

III 多控制器(用一个控制器去管理其他多个控制器)

为了便于管理控制器,iOS提供了2个比较特殊的控制器:UINavigationController、UITabBarController

四、UINavigationController

利用UINavigationController,可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型例子就是系统自带的“设置”应用。

iOS小技能:导航控制器(控制器、view的多种创建方式、控制器的生命周期)_生命周期_06

1、 UINavigationController的简单使用

1》UINavigationController的使用步骤

*初始化UINavigationController

*设置UIWindow的rootViewController为UINavigationController

*根据具体情况,通过push方法添加对应个数的子控制器 2、UINavigationController的子控制器(以栈的形式保存)

UINavigationController以栈的形式保存子控制器
@property(nonatomic,copy) NSArray *viewControllers;
@property(nonatomic,readonly) NSArray *childViewControllers;
//使用push方法能将某个控制器压入栈
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
//使用pop方法可以移除控制器、将栈顶的控制器移除
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;
//回到指定的子控制器
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
//回到根控制器(栈底控制器)
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;