前言
控制器管理(控制器之间的切换)
- 控制器、view的多种创建方式
- UINavigationController 的简单使用(添加、移除子控制器)
- UINavigationBar内容的设置
- 控制器的生命周期
I 控制器常见的创建方式
1.1 通过storyboard创建
- 先加载storyboard文件(Test是storyboard的文件名)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Test" bundle:nil];
- 接着初始化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
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
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 内存警告处理:
2.3 生命周期方法
众所周知,每一个UIViewController管理着一个由多个视图组成的树形结构,其中根视图保存在UIViewController的view属性中。UIViewController会懒加载它所管理的视图集,直到第一次访问view属性时,才会去加载或者创建UIViewController的视图集。
- 几种常用的加载或者创建UIViewController的视图集的方法如下。
·使用Storyboard。
·使用Nib文件。
·使用代码,即重写-
loadView
。
以上这些方法最终都会创建出合适的根视图并保存在UIViewController的view属性中,这是UIViewController生命周期的第一步。当UIViewController的根视图需要展示在页面上时,会调用-viewDidLoad方法。在这个方法中,我们可以做一些对象初始化相关的工作。
当UIViewController的视图在屏幕上的显示状态发生变化时,UIViewController会自动回调一些方法,以确保子类能够应对这些变化。
UIViewController被销毁前,还会回调-dealloc方法。我们一般通过重写该方法来主动释放不能被ARC自动释放的资源。
当执行到-viewDidAppear:方法时,表示视图已经在屏幕上渲染完成,即页面已经显示出来,正等待用户进行下一步操作。因此,执行到-viewDidAppear:方法的时间点是触发页面浏览事件的最佳时机。如果想要实现页面浏览事件的全埋点,
就需要使用iOS的“黑魔法”——Method Swizzling的相关技术
viewDidLoad的调用顺序
:
需要注意的是,此时,视图的bounds还没有确定。
- 如果使用代码创建视图集,-viewDidLoad方法会在-loadView方法调用结束之后运行。
- 如果使用Stroyboard或者Nib文件创建视图集,-viewDidLoad方法则会在-awakeFromNib方法之后调用。
III 多控制器(用一个控制器去管理其他多个控制器)
为了便于管理控制器,iOS提供了2个比较特殊的控制器:UINavigationController、UITabBarController
四、UINavigationController
利用UINavigationController,可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型例子就是系统自带的“设置”应用。
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;