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