UIWindow - 01窗口淺談

是什么?

  • UIWindow其實(shí)是一個(gè)特殊的UIView
  • 一個(gè)App里面,至少有一個(gè)UIWindow
  • App啟動(dòng)后,創(chuàng)建的第一視圖是UIWindow
    App啟動(dòng)后,創(chuàng)建的第一對(duì)象是UIApplication
  • 應(yīng)用程序之所以能顯示到屏幕上,完全是因?yàn)樗?code>UIWindow

  • 在加載info.plist 文件時(shí),判斷是否有指定Main 文件。
    • 如果有指定,就會(huì)去加載Main.Storyboard,它做了哪些操作呢?
      • 創(chuàng)建窗口
      • 初始化一個(gè)控制器
      • 將初始化的控制器設(shè)置為窗口的根控制器rootViewController。
      • 根控制器里面有個(gè)View
      • 將根控制器的view添加到窗口里。
      • 讓窗口顯示在屏幕上
    • 如果沒有指定,則需要手動(dòng)創(chuàng)建UIWindow

  • 手動(dòng)創(chuàng)建UIWindow
    • 在什么地方,什么時(shí)候創(chuàng)建?
      • UIApplication的代理類AppDelegate.m里創(chuàng)建UIWindow
      • Main 方法告知App啟動(dòng)完畢,調(diào)用AppDelegatedidFinishLaunchingWithOptions方法的時(shí)候,創(chuàng)建UIWindow
    • 怎么創(chuàng)建窗口?
      • window是必須是強(qiáng)引用(strong)
        @property (strong, nonatomic) UIWindow *window;
        • 為什么強(qiáng)引用 ?
          • 如果不強(qiáng)引用,那么出了didFinishLaunchingWithOptions 方法 ,UIWindow就被釋放了. 也就是說,UIWindow一顯示就會(huì)被銷毀了。
          • 當(dāng)設(shè)置控制器為窗口的根控制器時(shí),self.window.rootViewController = vc;
            • vc 被 rootViewController 引用
            • rootViewController 被 window 引用
            • 如果window不是strong,那么vc出了方法的{},就會(huì)被釋放了。
    • 示例代碼 :
      -- 應(yīng)用程序啟動(dòng)完成的時(shí)候調(diào)用
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
       -- 創(chuàng)建Window
      CGRect winFrame = [UIScreen mainScreen].bounds;
      self.window = [[UIWindow alloc]initWithFrame: winFrame];
      self.window.backgroundColor = [UIColor blueColor];
      
      -- 創(chuàng)建UIViewController
      UIViewController * vc = [[UIViewController alloc]init];
      vc.view.backgroundColor = [UIColor yellowColor];
      CGFloat vcY = winFrame.origin.y + 20;
      CGFloat vcH = winFrame.size.height -20;
      CGFloat vcW = winFrame.size.width;
      vc.view.frame = CGRectMake(0, vcY, vcW, vcH);
      
       -- 設(shè)置控制器為窗口的根控制器
      self.window.rootViewController = vc;
      
       -- 顯示窗口
      [self.window makeKeyAndVisible];
      return YES;
      }
      

  • 顯示窗口- makeKeyAndVisible 方法,它做了哪些操作?
    • 設(shè)置當(dāng)前窗口為App的主窗口,怎么證明?
      -- keyWindow 就是主窗口,
         它在"makeKeyAndVisible方法之后"有值就說明, "makeKeyAndVisible方法內(nèi)部,有設(shè)置當(dāng)前窗口為App的主窗口"。
      -- 否則,怎么說明"rootViewController時(shí)沒值",下一行代碼"makeKeyAndVisible時(shí)就有值"呢?
      
      self.window.rootViewController = vc;
      NSLog(@"rootViewController之后App的窗口 = %@",[UIApplication sharedApplication].keyWindow);
      
      [self.window makeKeyAndVisible];
      NSLog(@"makeKeyAndVisible之后App的窗口 = %@",[UIApplication sharedApplication].keyWindow);
      
      -- 打印結(jié)果
      rootViewController之后App的窗口 = (null)
      makeKeyAndVisible之后App的窗口 = <UIWindow: ....>
      
    • 顯示窗口,怎么證明?
      -- 注意: "rootViewController之后",有一個(gè)"hidden = YES (隱藏窗口)"
               "makeKeyAndVisible之后",就沒有了這個(gè)屬性,也就是說"hidden = NO (顯示窗口)"
      
      self.window.rootViewController = vc;
      NSLog(@"rootViewController之后 = %@",self.window);
      
      [self.window makeKeyAndVisible];
      NSLog(@"makeKeyAndVisible之后 = %@",self.window);
      
      -- 打印結(jié)果
      rootViewController之后 = <UIWindow: ...;  hidden = YES;...>
      makeKeyAndVisible之后 = < UIWindow: ...>
      

  • 簡(jiǎn)述:
    • [self.window makeKeyAndVisible];包含:
      • 設(shè)置當(dāng)前窗口為App的主窗口
      • 顯示窗口
        • 顯示窗口
        • 設(shè)置跟窗口的frame一樣的根控制view的frame
        • 把窗口根控制的view添加到到窗口上面
    • self.window.hidden = NO;(顯示窗口),可替換 [self.window makeKeyAndVisible];

  • self.window.hidden = NO; 做了哪些事情?
    --  self.window.hidden 做了哪些事情
    1. 顯示窗口
    2. 把窗口根控制器添加到窗口上面.
      2.1 在self.window.hidden = NO; 之前,有寫"把窗口根控制的view添加到到窗口上面"
          那么,會(huì)顯示"根控制器(vc)view的自定義frame"
          代碼如下:
                self.window.rootViewController = vc; -- 設(shè)置window的根控制器
                -- 把窗口根控制的view添加到到窗口上面
                [self.window addSubview:self.window.rootViewController.view]; 
                self.window.hidden = NO;
      2.2 直接寫self.window.hidden = NO; 沒寫"把窗口根控制的view添加到到窗口上面"的代碼, 
          會(huì)顯示窗口,也會(huì)顯示根控制器的view, "但不是自定義view的frame"。
          說明 self.window.hidden = NO; 
          后期還是會(huì)"把窗口根控制的view添加到到窗口上面"
          并且設(shè)置跟"窗口的frame一樣的根控制view的frame"
          代碼如下: 
                self.window.rootViewController = vc; 
                self.window.hidden = NO;
    
  • 效果圖:

獲取設(shè)置窗口

  • [UIApplication shareApplication].windows //本應(yīng)用中打開的UIWindow列表
  • [UIApplication shareApplication].keyWindows // 主窗口
  • - (void) makeKeyWindow; 讓當(dāng)前UIWindow變成keyWindow(主窗口)
  • view.window 獲得某個(gè)UIView所在的UiWindow

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容