控制器有一個(gè)view
屬性羽历,我們經(jīng)常在控制器中通過(guò)self.view
來(lái)訪問(wèn)。這個(gè)view是一個(gè)很有意思的東西淡喜。
首先要明白這個(gè)view
到底是什么東西秕磷。
一個(gè)控制器成為window的根控制器的時(shí)候,當(dāng)這個(gè)界面即將顯示拆火,控制器的view會(huì)被加到window中用來(lái)顯示界面跳夭。正常情況下控制器自帶的view是"無(wú)色透明"
的涂圆。
如果你在設(shè)置window的根控制器前創(chuàng)建一個(gè)Button直接加到window上,此時(shí)button出現(xiàn)在window上币叹,但是在控制器的view的下面润歉。此時(shí)點(diǎn)擊按鈕會(huì)發(fā)現(xiàn)按鈕并不會(huì)響應(yīng)點(diǎn)擊。
這是因?yàn)榭刂破鞯膙iew攔截了點(diǎn)擊事件颈抚,這說(shuō)明它并非真的完全透明
(因?yàn)槿绻耆该鞑锐茫敲床粫?huì)攔截點(diǎn)擊事件,可以設(shè)置viewController.view.alpha = 0
來(lái)驗(yàn)證贩汉,此時(shí)按鈕就可以響應(yīng)點(diǎn)擊)驱富。事實(shí)上view是一個(gè)backgroundColor
為clearColor
的視圖,clearColor
是幾乎透明的顏色
但是并非完全透明
匹舞,也就是說(shuō)當(dāng)有類似點(diǎn)擊事件發(fā)生的時(shí)候褐鸥,clearColor
背景的view會(huì)攔截點(diǎn)擊事件,因?yàn)樗⒎?code>完全透明赐稽。
所以可以說(shuō)控制器的view
是一個(gè)看不見(jiàn)摸得著
的東西...
另外view
是懶加載
的叫榕,也就是說(shuō),只有真正使用到控制器的view
的時(shí)候它才會(huì)被創(chuàng)建出來(lái)姊舵。它就是在控制器的-loadView
方法中創(chuàng)建出來(lái)的晰绎。
- (void)loadView
{
// 類似這種實(shí)現(xiàn)
// 可能還會(huì)進(jìn)行更多的操作,比如判斷是否有指定storyboard括丁,如果是就會(huì)加載storyboard中控制器的view等操作
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor clearColor];
// ...
_view = view;
}
前面說(shuō)過(guò)荞下,view
是懶加載
的,所以當(dāng)使用self.view
的時(shí)候:
- (UIView *)view
{
// 類似這種實(shí)現(xiàn)
if (_view == nil) {
[self loadView];
[self viewDidLoad];
}
return _view;
}
當(dāng)_view
為nil的時(shí)候會(huì)調(diào)用loadView
方法方法史飞,此時(shí)系統(tǒng)默認(rèn)會(huì)創(chuàng)建一個(gè)UIView對(duì)象并將其賦值給_view
尖昏,此時(shí)_view
有了值,接著調(diào)用viewDidLoad
方法祸憋。
當(dāng)再次訪問(wèn)self.view
的時(shí)候会宪,因?yàn)?code>_view已經(jīng)有值,所以會(huì)直接返回_view
蚯窥。這也是為什么loadView
以及viewDidLoad
方法只會(huì)執(zhí)行一次掸鹅。
之前的文章提到過(guò),在給window設(shè)置完根控制器拦赠,根控制器的view并不是馬上就被加到window上巍沙,也就是說(shuō)此時(shí)view還未創(chuàng)建。在[self.window makeKeyAndVisible]
之后界面即將顯示的時(shí)候荷鼠,這時(shí)候需要用到view句携,此時(shí)就會(huì)調(diào)用view的getter方法,接著執(zhí)行loadView
允乐,在接著執(zhí)行viewDidLoad
等一系列方法矮嫉。
現(xiàn)在我們知道view是懶加載的削咆,所以如果在[self.window makeKeyAndVisible]
之前就用到控制器的view,那么它就會(huì)"提前”創(chuàng)建蠢笋。
NSLog(@"%@", viewController.view); // 此時(shí)用到view,就會(huì)創(chuàng)建view
現(xiàn)在我們知道控制器的view
是通過(guò)loadView
方法創(chuàng)建的了拨齐,所以我們可以覆寫這個(gè)方法來(lái)達(dá)到改變控制器的自帶view
的目的:
- (void)loadView
{
JYView *view = [[JYView alloc] initWithFrame:[UIScreen mainScreen].bounds];
view.background = [UIColor blueColor];
_view = view;
}
此時(shí)我們就改變了控制器原本自動(dòng)創(chuàng)建的view,現(xiàn)在使用self.view
則得到的是JYView的對(duì)象
昨寞。