文章目录

前言ViewController执行过程的探讨ViewControllerOne

函数介绍顺序引入ViewControllerSecond引入

ViewControllerOne点击执行到ViewControllerSecond的2种情况View加载的分析Viewdidload之后发生地事情viewWillAppear 和 viewDidAppear 中间的过程

viewWillDisappear 和 viewDidDisappear

结尾

前言

在写项目的时候,ViewController是最基本的东西,只是知道他用来加载视图,控件的全能函数,把一些控件啥的不管都写在里面去了,通过了解ViewController的生命周期发现他的内部存在许多函数

ViewController执行过程的探讨

思路:设置2个界面,采用P resent同级跳转的方法推出界面,之后在第二界面设置返回Button,每个界面的每个函数打印操作过程就能看到先后顺序了代码

ViewControllerOne

先进行一下ViewControllerOne的初始化加载,函数放到后面去讲,和平常不一样的是打印了每个函数执行过程

#import

NS_ASSUME_NONNULL_BEGIN

@interface ViewControllerSecond : UIViewController

// Button跳转到下一界面

@property (nonatomic, strong)UIButton* buttonReturn;

@end

NS_ASSUME_NONNULL_END

#import "ViewControllerSecond.h"

#import "Masonry.h"

@interface ViewControllerSecond ()

@end

@implementation ViewControllerSecond

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view.

NSLog(@"%s",__func__);

self.view.backgroundColor = [UIColor orangeColor];

_buttonReturn = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[_buttonReturn setTitle:@"Return" forState:UIControlStateNormal];

[_buttonReturn addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:_buttonReturn];

[_buttonReturn mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.mas_offset(150);

make.left.mas_offset(200);

make.width.mas_offset(200);

make.height.mas_offset(100);

}];

}

- (void)loadView {

[super loadView];

NSLog(@"%s",__func__);

}

- (void)viewWillAppear:(BOOL)animated {

NSLog(@"%s",__func__);

}

- (void)viewWillLayoutSubviews {

NSLog(@"%s",__func__);

}

- (void)viewWillDisappear:(BOOL)animated {

NSLog(@"%s",__func__);

}

- (void)viewDidAppear:(BOOL)animated {

NSLog(@"%s",__func__);

}

- (void)viewDidLayoutSubviews {

NSLog(@"%s",__func__);

}

- (void)viewDidDisappear:(BOOL)animated {

NSLog(@"%s",__func__);

}

- (void)press {

NSLog(@"-------------Second is Back!--------------");

[self dismissViewControllerAnimated:YES completion:nil];

}

/*

#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

// Get the new view controller using [segue destinationViewController].

// Pass the selected object to the new view controller.

}

*/

@end

执行第一界面的加载

函数介绍

结果:从上到下一次打印了VIew执行过程函数viewDidLoad:在视图加载后被调用,如果是在代码中创建的视图加载器,他将会在loadView方法后被调用,如果是从nib视图页面输出,他将会在视图设置好后后被调用。只会被调用一次,之后进入这个ViewController不调用此函数loadView:每次访问controller的view(比如controller.view、self.view)且view为nil,loadView方法就会被调用。用于创建Controller的ViewviewWillAppear: 视图将要显示viewWillLayoutSubviews: 控制器的view将要布局子控件(在这个方法里,部署需要改变重新刷新view的代码,功能类似view的layoutSubViews()这个方法,需要注意的是,这个方法里一般都需要重置的view的frame,宽度和高度的获取,因此view的frame一般都写在这个方法里)viewDidLayoutSubviews: 控制器的view布局子控件完成viewDidAppear: 视图已经显示viewWillDisappear: 视图将要消失viewDidDisappear: 视图已经消失,在Controller被切换时调用,第二个视图出现后第一个视图消失

顺序引入

我们发现上述结果只打印到了DidAppear函数,并没有出现DIss appear的两个函数,如上所述,dis appear是界面即将消失的时候出现的函数,我们并没有切换界面,所以这个函数也不会调用接下来引入界面二,看diss appear的调用位置

ViewControllerSecond引入

代码

#import

NS_ASSUME_NONNULL_BEGIN

@interface ViewControllerSecond : UIViewController

// 返回第一界面的Button

@property (nonatomic, strong)UIButton* buttonReturn;

@end

NS_ASSUME_NONNULL_END

#import "ViewControllerSecond.h"

#import "Masonry.h"

@interface ViewControllerSecond ()

@end

@implementation ViewControllerSecond

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view.

NSLog(@"%s",__func__);

self.view.backgroundColor = [UIColor orangeColor];

_buttonReturn = [UIButton buttonWithType:UIButtonTypeRoundedRect];

[_buttonReturn setTitle:@"Return" forState:UIControlStateNormal];

[_buttonReturn addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:_buttonReturn];

[_buttonReturn mas_makeConstraints:^(MASConstraintMaker *make) {

make.top.mas_offset(150);

make.left.mas_offset(200);

make.width.mas_offset(200);

make.height.mas_offset(100);

}];

}

- (void)loadView {

[super loadView];

NSLog(@"%s",__func__);

}

- (void)viewWillAppear:(BOOL)animated {

NSLog(@"%s",__func__);

}

- (void)viewWillLayoutSubviews {

NSLog(@"%s",__func__);

}

- (void)viewWillDisappear:(BOOL)animated {

NSLog(@"%s",__func__);

}

- (void)viewDidAppear:(BOOL)animated {

NSLog(@"%s",__func__);

}

- (void)viewDidLayoutSubviews {

NSLog(@"%s",__func__);

}

- (void)viewDidDisappear:(BOOL)animated {

NSLog(@"%s",__func__);

}

- (void)press {

NSLog(@"-------------Second is Back!--------------");

[self dismissViewControllerAnimated:YES completion:nil];

}

/*

#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

// Get the new view controller using [segue destinationViewController].

// Pass the selected object to the new view controller.

}

*/

@end

ViewControllerOne点击执行到ViewControllerSecond的2种情况

在这里出现2种不同的情况情况一:在第二界面加载出来的时候第一界面的dissappear并没有出现,后来发现我在第一界面的Button事件里面缺少了这句话View.modalPresentationStyle = UIModalPresentationFullScreen;的意思是弹出并且是占据了整个屏幕,接下来加上这句话- 分析:看到上述结果就是一个View加载的全部过程了,首先我们得知道,控制器 view 是通过懒加载的方式进行加载的,即用到的时候再加载。,所以系统先去loadView里执行了一遍我们重写的方法[super loadView]; 接下来再去加载View

View加载的分析

View加载的过程(转):在 view 加载过程中首先会调用 loadView 方法,在这个方法中主要完成一些关键 view 的初始化工作,比如 UINavigationViewController 和 UITabBarController 等容器类的 ViewController;接下来就是加载 view,加载成功后,会接着调用 viewDidLoad 方法,这里要记住的一点是,在 loadView 之前,是没有 view 的,也就是说,在这之前,view 还没有被初始化。完成 viewDidLoad 方法后,ViewController 里面就成功的加载 view了为此我做一尝试,在loadView函数里面不写[super loadView],结果如下,我吧Second View的load View函数改了,其他并未变化

- (void)loadView {

// [super loadView];

NSLog(@"%s",__func__);

}

直接看到,函数回去不断的重复的寻找View,也就是在loadView接下来到Viewdidload发现VIew为空,再次回去寻求View,如此重复若 loadView 没有加载 view,即为 nil,viewDidLoad 会一直调用 loadView 加载 view,因此构成了死循环,程序即卡死,所以我们常在 ViewDidLoad 里创建 view。

Viewdidload之后发生地事情

参考大佬博客UIViewController生命周期通过图片可以看到viewWillAppear总是出现在ViewdidLoad之后,但不是立即,当你只是引用了属性 view,却没有立即把 view 添加到任何已经展示的视图上时,viewWillAppear 不会被调用,这在 view 被外部引用时,就会发生。当然,随着 ViewController 的多次推入,多次进入子页面后返回,该方法会被多次调用。与 viewDidLoad 不同,调用该方法就说明控制器一定会显示。

viewWillAppear 和 viewDidAppear 中间的过程

viewWillLayoutSubviews- viewDidLayoutSubviews两个方法被调用了viewWillLayoutSubviews

该方法在通知控制器将要布局 view 的子控件时调用。每当视图的 bounds 改变,view 将调整其子控件位置。默认实现为空,可重写以在 view 布局子控件前做出改变。该方法调用时,AutoLayout 未起作用。 viewDidLayoutSubviews

该方法在通知控制器已经布局 view 的子控件时调用。默认实现为空,可重写以在 view 布局子控件后做出改变。该方法调用时,AutoLayout 未起作用。

viewWillDisappear 和 viewDidDisappear

在我们推出了视图二的时候,视图二的VIewdi dLoad函数完成了,出现了视图一的viewWillDisappear,而在视图二的ViewDidappear出现之后,视图一的viewDidDisappear才完成,也就是说在第二个界面加载开始到加载完成,第一个界面才会完全的消失!!

结尾

对于present和push只是简单的提了一下,present只是弹出,所以并么有全部的覆盖第一界面,今天主要了解UIView Controller的加载过程和生命周期,接下来会进一步学习present和push的区别

推荐链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: