3.UIViewController详解

 一. UIViewController,视图控制器,它是UIKit中非常重要的组成部分。它由控制器+View两部分组成。

控制器功能:

-》实现代码逻辑,决定它自带的View的界面显示。

-》控制器与控制器之间的通信,如传值,跳转。

-》以及与Model和View间的信息传递。

-》可以通过addChirldViewController来添加子控制器。(如抽屉效果,多选tableView都是采用此方式)

视图功能:

-》向用户展示信息

-》可以添加子视图,设置子视图的层别

-》可以接收响应事件(用户在触摸后屏幕后就会形成一个基于触摸点的UIEvent事件)

这个事件通过 application - > keyWindow- > UIViewController(可选择,如果没有则直接传递给下一级)-》View-》subView -》.....->知道最终找到触摸点所在的那个位置对应的视图->查找该处视图是否有添加响应时间-》没有则自动释放-》有则通过该触摸点View->父视图-》控制器(没有直接向上一级出传递)-》keyWindow-》applcation。

二. UIViewController的生命周期

经过测试执行顺序由上到下:

1. 首先给视图控制器分配空间,然后初试化,接着创建唯一的UIView视图。

2016-03-10 22:24:47.029 Demo_10_抽屉效果[74967:4603110] +[MainViewController alloc],分配空间

2. init方法初始化,将这块内存的数据清空;系统也提供了init的改写方法,在初试化的时候直接连View一起加载好,

视图控制器初试化好之后就是加载VIew,加载View有三种方式.

-> 通过initWithCoder:从故事版中加载

-> 通过initWithNibName:从xib中加载

-> 通过自己使用代码进行创建。

在没有故事版和storyBoard调用次方法视图可以从Xib  StroyBoard 代码中创建

2016-03-10 22:24:47.029 Demo_10_抽屉效果[74967:4603110] -[MainViewController initWithCoder:],从故事板归档文件中加载视图出来了

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 从xib二进制文件中加载出来了

将解压或者代码创建视图加载出来

3. loadView,将从storyBoard或者Nib文件,或者代码创建的View加载到系统中

2016-03-10 22:24:47.061 Demo_10_抽屉效果[74967:4603110] -[MainViewController loadView],加载控制器的唯一视图View视图已经加载出来了

4. View已经加载出来了,如果改视图控制器不销毁,只是界面切换,那么此方法只会执行一次。

2016-03-10 22:24:47.062 Demo_10_抽屉效果[74967:4603110] -[MainViewController viewDidLoad],视图已经加载出来了  视图将要显示在手机屏幕上

5. View将要显示到屏幕上,通常我们需要进行一些预先加载的操作可以写到这里,比如添加通知事件。

2016-03-10 22:24:47.063 Demo_10_抽屉效果[74967:4603110] -[MainViewController viewWillAppear:],视图将要显示在屏幕界面上了

6. 因为ViewFrame已经计算好了,且将要显示到屏幕上,但是它的子视图还没有固定好,所有先要调用子视图的两个方法

视图开始布局子视图了,当子视图的约束写在此方法中时,当视图变化时候,子视图会跟着变化。

2016-03-10 22:24:47.069 Demo_10_抽屉效果[74967:4603110] -[MainViewController viewWillLayoutSubviews],视图开始布局自视图了

. 2016-03-10 22:24:47.069 Demo_10_抽屉效果[74967:4603110] -[MainViewController viewDidLayoutSubviews],视图的子视图已经布局完了

7.  subView布局好之后,View才开始真正的显示视图

[MainViewController viewDidAppear:],视图已经出现在屏幕上了

8.  View将要消失

-(void)viewWillDisappear:(BOOL)animated

9. View已经消失在界面上了。通常我们一些通知事件移除可以写在此方法中。

- (void)viewDidDisappear:(BOOL)animated

10.控制器收到了内存不足警告

- (void)didReceiveMemoryWarning

11.下面两个是死亡方法

- (void)viewDidUnLoad 视图警告内存不足可能被卸掉,下次就会继续执行viewDidLoad

- (void)dealloc 当前视图控制器销毁

三 . UIViewController中布局子视图的时机。

通常我们所说的布局子视图其实就是调用layOutSubViews.应为只有这个方法才会对父视图上的所有子视图进行统一的计算,然后再进行调用。

下面请看这几个方法:

1. layOutSubViews: 这个方法默认是什么都不做的,我们需要布局的子视图对象的frame计算方式都可以写在这里。

2. setNeedsLayout方法:将调用者标记为需要进行重新布局,采取异步调用layoutIfNeed刷行布局(异步及另外开辟线程,不会立即刷新)。同时会调用layOutSubViews的方式刷新子视图布局。

3.layoutIfNeeded方法:如果该对象有需要刷新的标记,则会立即自动调用layoutSubViews。(如果没有这个标记的话,则不会马上调用layOutSubViews);视图在第一次看时的时候都会有需要刷新的标记,所以可以调用  [xxx.view layOutIfNeeded]

4. 子视图重绘改变布局:

-drawRect:(CGRect)rect方法:重写此方法执行重绘任务。

-setNeedsDisplay方法,标记为需要绘,异步执行上面的方法进行绘制。例如当我们在做画笔工具的时候需要对路径进行实时勾勒,可以调用此方法。

-setNessdsDisplayInRect:(CGRect)invalidRect方法:标记为需要局部重绘。

#pragma mark NSObject 线程安全与运行环境加载
+ (void)load {
NSLog(@"%s",__func__);
} + (void)initialize {
NSLog(@"%s",__func__);
} + (instancetype)alloc {
NSLog(@"%s,分配空间",__func__);
return [super alloc];
} //+ (instancetype)allocWithZone:(struct _NSZone *)zone {
// NSLog(@"%s,分配空间",__func__);
// return [self allocWithZone:zone];
//} - (instancetype)init {
NSLog(@"%s,初始化空间",__func__);
return [self init];
} //- (instancetype)initWithCoder:(NSCoder *)aDecoder {
// NSLog(@"%s,从归档文件总加载",__func__);
// return [super initWithCoder: aDecoder];
//} - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
NSLog(@"%s,从Nib二进制文件中加载",__func__);
return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
} - (void)loadView {
NSLog(@"%s,加载控制器的唯一视图View",__func__);
[super loadView];
} - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
NSLog(@"%s,视图的size发生改变",__func__);
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
} - (void)viewDidLoad {
NSLog(@"%s,视图已经加载出来了",__func__);
[super viewDidLoad];
} - (void)viewWillAppear:(BOOL)animated {
NSLog(@"%s,视图将要显示在屏幕界面上了",__func__);
[super viewWillAppear:animated];
} //- (void)viewWillLayoutSubviews {
// NSLog(@"%s,视图开始布局自视图了",__func__);
// [super viewWillLayoutSubviews];
// UIButton* button = [[UIButton alloc]initWithFrame:CGRectMake(20, 20, 100, 30)];
// [button setTitle:@"test btn" forState:UIControlStateNormal];
// [button setTintColor:[UIColor greenColor]];
// [self.view addSubview:button];
//}
//
//- (void)viewDidLayoutSubviews {
// NSLog(@"%s,视图的子视图已经布局完了",__func__);
// [super viewDidLayoutSubviews];
//} - (void)viewDidAppear:(BOOL)animated {
NSLog(@"%s,视图已经出现在屏幕上了",__func__);
[super viewDidAppear:animated];
} - (void)viewWillDisappear:(BOOL)animated {
NSLog(@"%s,视图将要消失了",__func__);
[super viewWillDisappear:animated];
} - (void)viewDidDisappear:(BOOL)animated {
NSLog(@"%s,视图已经消失了",__func__);
[super viewDidDisappear:animated];
} #pragma mark 可选择性的
- (void)loadViewIfNeeded {
[super loadViewIfNeeded];
}
上一篇:QuickBI助你成为分析师-数据建模(二)


下一篇:status状态栏实现字符串走动