作者:Mitchell
一、一些基本的概念
- 调用时间:第一次使用控制器的view的时候
- 作用:加载控制器的view
- 在loadView中创建自己的view可以不给frame,系统会自动设置控制器view的尺寸。
- 注意:
- 只要重写loadView,里面就不要调用[super loadView],因为如果我们重写了loadView的方法,就代表着我们需要初始化的是自己所创建的view,而不再是系统默认的view,如果再调用[super loadView]就显得很多余了。
[super loadView]
:回去判断有么有指定的storyboard,如果有,就会帮你加载storyboard描述的的控制器的view。 - 在loadView方法中,如果没有给控制器的view赋值,就不能获取控制器的view,否则会造成死循环。
- 只要重写loadView,里面就不要调用[super loadView],因为如果我们重写了loadView的方法,就代表着我们需要初始化的是自己所创建的view,而不再是系统默认的view,如果再调用[super loadView]就显得很多余了。
二、偏底层的实现
- 创建controller:(
用MitchellViewController来举例
):- 首先调用controller的init方法(我们用init方法来初始化controller)
- init方法会默认调用initWithNibName
- 会判断nibName有没有值
- 如果没有值,系统就会去寻找有没有MitchellView.xib,如果有,就直接加载
- 上一步若没有加载出view,那么系统会默认去寻找MitchellViewController.xib文件,如果有就加载
- 如果以上步骤都没有,那么系统就会默认创建一个空的view。
- loadView内部的实现:
- 只有在我们需要让view显示的时候才会去loadView,也就是这里其实调用的是view的get方法。
- 我本来想重写一下view的get方法,
但是这里注意了
,_view这个成员变量使用了@package修饰。这个修饰符是什么意思呢?这个@package说明这个UIView成员变量只能在框架内被访问到,现在我们自定义的viewController当然不再UIKit这个框架内,所以不能访问到了。 - 但是我们还是能大概推测出在get方法中的实现:
-(void)loadView{
[super loadView];
NSLog(@"%s",__func__);
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"%s",__func__);
}
打印一下结果:
-[ViewController loadView]
-[ViewController viewDidLoad]
那就大概写出了get方法中的实现方式:
-(UIView *)view{
if (!_view) {
[self loadView];
[self viewDidLoad];
}
return _view;
}
- 再探究一下关于controller默认创建的空view是以什么样的方式加在window上的
- 方案一: 我们创建了一个button放在window上,并将controller的view的backgroundColor设为clearColor
UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
button.center = CGPointMake(200, 200);
[self.window addSubview: button];
ViewController *vc = [[ViewController alloc] init];
vc.view.backgroundColor = [UIColor clearColor];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
- 方案二:我们将view的color设置为whiteColor并将透明度设置为0.1
ViewController *vc = [[ViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
vc.view.alpha = 0.01;
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
- 结论:我们发现只有第二种方案当我点击加在window上面的按钮的时候,按钮是有反应的,所以controller所创建的view应该是几乎透明的,而并非是clearcolor。