UIWindow
-
基本概念
- 一個(gè)iOS程序之所以能顯示到屏幕上,完全是因?yàn)樗蠻IWindow,是一種特殊的UIView,通常在一個(gè)app中至少會有一個(gè)UIWindow
- iOS程序啟動完畢后,創(chuàng)建的第一個(gè)視圖控件就是UIWindow,接著創(chuàng)建控制器的view,最后將控制器的view添加到UIWindow上,于是控制器的view就顯示在屏幕上了
- 基本屬性
-
- (void)addSubview:(UIView *)view;直接將view添加到UIWindow中,但并不會理會view對應(yīng)的UIViewController -
@property(nonatomic,retain) UIViewController *rootViewController;自動將rootViewController的view添加到UIWindow中,負(fù)責(zé)管理rootViewController的生命周期 -
- (void)makeKeyWindow;讓當(dāng)前UIWindow變成keyWindow(主窗口) -
- (void)makeKeyAndVisible;讓當(dāng)前UIWindow變成keyWindow,并顯示出來
-
-
UIWindow 顯示
程序啟動首先加載 plist 文件,看有沒有設(shè)置 main.storyboard
如果有,就加載storyboard,并且創(chuàng)建窗口
-
自動加載storyboard 并創(chuàng)建window
- 創(chuàng)建 UIWindow
- 創(chuàng)建和設(shè)置 UIWindow 的 rootViewController
- 顯示窗口
- 在程序啟動的時(shí)候就會執(zhí)行這3步。和代碼的不同之處,代碼創(chuàng)建窗口是程序啟動完畢的時(shí)候才創(chuàng)建的。
- 通過storyboard加載程序,窗口都交給storyboard管理,不需要自己管
-
手動創(chuàng)建 UIWindow
```
// 1. 創(chuàng)建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];`
// 層級關(guān)系(UIWindowLevelNormal < UIWindowLevelStatusBar < UIWindowLevelAlert)
// self.window.windowLevel = UIWindowLevelNormal;
//2. 設(shè)置根控制器
UIViewController *vc = [[ViewController alloc] init];
self.window.rootViewController = vc;
//3. 顯示窗口
[self.window makeKeyAndVisible];```
控制器 View 的創(chuàng)建
-
從 storyboard 加載
-
創(chuàng)建窗口
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
-
加載 main.storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];- name:storyboard的名稱
- boudle:nil。
nil = [NSBudle mainBundle]
-
加載控制器
- 加載箭頭指向的控制器
UIViewController *vc = [storyboard instantiateInitialViewController]; - 加載有標(biāo)示的控制器
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"vc"];
- 加載箭頭指向的控制器
-
設(shè)置根控制器
self.window.rootViewController = vc;
-
顯示窗口
[self.window makeKeyAndVisible]
-
創(chuàng)建窗口
-
addSubView 和 rootViewController的區(qū)別
直接用
addSubView,控制器會被釋放,控制器就不能處理事件直接用
addSubView,控制器的view不會自動旋轉(zhuǎn)。用
rootViewController,控制器不會被釋放,而且控制器的view會自動旋轉(zhuǎn)旋轉(zhuǎn)事件->
UIApplication ->Window->rootViewController ->旋轉(zhuǎn)控制器的view-
windowLevel:
UIWindowLevelNormal < UIWindowLevelStatusBar < UIWindowLevelAlert-
UIWindowLevelNormal: 默認(rèn)窗口的層級 -
UIWindowLevelStatusBar: 狀態(tài)欄,鍵盤、 -
UIWindowLevelAlert:UIActionSheet,UIAlearView
-
XIB Creat Controller
-
通過XIB創(chuàng)建控制器的view
- xib注意點(diǎn):(演示沒有的后果)
- xib里面必須有一個(gè)view描述控制器的view,因?yàn)榭刂破鞯膙iew 屬性必須有值。
- xib需要指定描述哪一個(gè)控制器,描述UIView不需要,因?yàn)閤ib里 面可以描述很多UIView,不能固定死,但是控制器就不一樣了,一個(gè)xib就用來描述一個(gè)控制器。
- xib里面可能有很多view,需要拖線指明哪個(gè)是控制器的view
-
XIB創(chuàng)建步驟
- 創(chuàng)建Xib文件
- xib文件要有一個(gè)view描述控制器
- 連線,告訴xib描述哪個(gè)控制器,設(shè)置文件擁有者為控制器
- 調(diào)用initWithNibName創(chuàng)建控制器
// 1.創(chuàng)建窗口 self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; // 2.設(shè)置窗口的根控制器 XMGViewController *vc = [[XMGViewController alloc] init]; self.window.rootViewController = vc; // 3.顯示窗口 [self.window makeKeyAndVisible];-
init底層調(diào)用initWithNibName
- initWithNibName:底層做了一些事情
- 1.判斷有沒有指定nibName,指定了,就會加載
- 2.判斷下有沒有跟控制器類名同名的xib但是不帶controller,如果有,就直接加載
- 3.判斷下有沒有跟控制器類名同名的xib,如果有,就直接加載
- 4.
如果都沒有系統(tǒng)就會給我們創(chuàng)建一個(gè)nil的View(不是黑色的,也不是透明的,是幾乎透明的。解釋:如過創(chuàng)建一個(gè)直接添加在 window 上的 button,是不能點(diǎn)擊的,因?yàn)榱酥虚g隔了一層系統(tǒng)給我們創(chuàng)建的 view,如果控制器的view完全透明, 里面的可以點(diǎn)擊 vc.view.alpha = 0;)
-
XIB 創(chuàng)建控制器 view 的使用時(shí)機(jī)
- 當(dāng)控制器的view界面是固定的時(shí)候
- 為什么想要用xib或者storyboard創(chuàng)建控制器,其實(shí)就是想要使用它們來描述我們控制器的view
-
XIB 和storyboard的區(qū)別
- storyboard已經(jīng)指定了控制器的view,不需要我們管,xib需要我們手動管理。
-
-
LoadView(加載控制器的view)
- 第一次使用控制器的view就會調(diào)用這個(gè)方法,加載控制器的view
- 在開發(fā)中,如果重寫loadView,內(nèi)部就不會調(diào)用[super loadView]
- 在開發(fā)中,只要重寫了loadView,表示不需要系統(tǒng)幫我們創(chuàng)建控制器的view,需要自定義控制器的view
- 使用場景:一開始就想要控制器的view顯示一張圖片,解決:讓控制器的view直接成為UIImageView
- 注意點(diǎn):
在沒有給控制器的view賦值之前,不能調(diào)用控制器的view的get方法.
- (void)loadView { VCView *view = [[VCView alloc] initWithFrame:[UIScreen mainScreen].bounds]; // UIImageView *imageView = [UIImageView alloc] initWithFrame:<#(CGRect)#> self.view = view; }isViewLoaded方法判斷一個(gè)UIViewController的view是否已經(jīng)被加載
控制器的 View 是懶加載的,只加載一次,所以在 ViewDidLoad 里面是不能修改的,比如說背景顏色等。