iOS學習之 UIWindow

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

      1. 創建 UIWindow
      2. 創建和設置 UIWindow 的 rootViewController
      3. 顯示窗口
        • 在程序啟動的時候就會執行這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 加載

    1. 創建窗口
      • self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    2. 加載 main.storyboard
      • UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
      • name:storyboard的名稱
      • boudle:nil。 nil = [NSBudle mainBundle]
    3. 加載控制器
      • 加載箭頭指向的控制器UIViewController *vc = [storyboard instantiateInitialViewController];
      • 加載有標示的控制器UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"vc"];
    4. 設置根控制器
      • self.window.rootViewController = vc;
    5. 顯示窗口
      • [self.window makeKeyAndVisible]
  • addSubView 和 rootViewController的區別

    • 直接用addSubView,控制器會被釋放,控制器就不能處理事件

    • 直接用addSubView,控制器的view不會自動旋轉。

    • rootViewController,控制器不會被釋放,而且控制器的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創建步驟

      1. 創建Xib文件
      2. xib文件要有一個view描述控制器
      3. 連線,告訴xib描述哪個控制器,設置文件擁有者為控制器
      4. 調用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 里面是不能修改的,比如說背景顏色等。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容