UIWindow - 01窗口浅谈

是什么?

  • UIWindow其实是一个特殊的UIView
  • 一个App里面,至少有一个UIWindow
  • App启动后,创建的第一视图是UIWindow
    App启动后,创建的第一对象是UIApplication
  • 应用程序之所以能显示到屏幕上,完全是因为它有UIWindow

  • 在加载info.plist 文件时,判断是否有指定Main 文件
    • 如果有指定,就会去加载Main.Storyboard,它做了哪些操作呢?
      • 创建窗口
      • 初始化一个控制器
      • 将初始化的控制器设置为窗口的根控制器rootViewController
      • 根控制器里面有个View
      • 将根控制器的view添加到窗口里。
      • 让窗口显示在屏幕上
    • 如果没有指定,则需要手动创建UIWindow

  • 手动创建UIWindow
    • 在什么地方,什么时候创建?
      • UIApplication的代理类AppDelegate.m里创建UIWindow
      • Main 方法告知App启动完毕,调用AppDelegatedidFinishLaunchingWithOptions方法的时候,创建UIWindow
    • 怎么创建窗口?
      • window是必须是强引用(strong)
        @property (strong, nonatomic) UIWindow *window;
        • 为什么强引用 ?
          • 如果不强引用,那么出了didFinishLaunchingWithOptions 方法 ,UIWindow就被释放了. 也就是说,UIWindow一显示就会被销毁了
          • 当设置控制器为窗口的根控制器时,self.window.rootViewController = vc;
            • vc 被 rootViewController 引用
            • rootViewController 被 window 引用
            • 如果window不是strong,那么vc出了方法的{},就会被释放了。
    • 示例代码 :
      -- 应用程序启动完成的时候调用
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
       -- 创建Window
      CGRect winFrame = [UIScreen mainScreen].bounds;
      self.window = [[UIWindow alloc]initWithFrame: winFrame];
      self.window.backgroundColor = [UIColor blueColor];
      
      -- 创建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);
      
       -- 设置控制器为窗口的根控制器
      self.window.rootViewController = vc;
      
       -- 显示窗口
      [self.window makeKeyAndVisible];
      return YES;
      }
      

  • 显示窗口- makeKeyAndVisible 方法,它做了哪些操作?
    • 设置当前窗口为App的主窗口,怎么证明?
      -- keyWindow 就是主窗口,
         它在"makeKeyAndVisible方法之后"有值就说明, "makeKeyAndVisible方法内部,有设置当前窗口为App的主窗口"。
      -- 否则,怎么说明"rootViewController时没值",下一行代码"makeKeyAndVisible时就有值"呢?
      
      self.window.rootViewController = vc;
      NSLog(@"rootViewController之后App的窗口 = %@",[UIApplication sharedApplication].keyWindow);
      
      [self.window makeKeyAndVisible];
      NSLog(@"makeKeyAndVisible之后App的窗口 = %@",[UIApplication sharedApplication].keyWindow);
      
      -- 打印结果
      rootViewController之后App的窗口 = (null)
      makeKeyAndVisible之后App的窗口 = <UIWindow: ....>
      
    • 显示窗口,怎么证明?
      -- 注意: "rootViewController之后",有一个"hidden = YES (隐藏窗口)"
               "makeKeyAndVisible之后",就没有了这个属性,也就是说"hidden = NO (显示窗口)"
      
      self.window.rootViewController = vc;
      NSLog(@"rootViewController之后 = %@",self.window);
      
      [self.window makeKeyAndVisible];
      NSLog(@"makeKeyAndVisible之后 = %@",self.window);
      
      -- 打印结果
      rootViewController之后 = <UIWindow: ...;  hidden = YES;...>
      makeKeyAndVisible之后 = < UIWindow: ...>
      

  • 简述:
    • [self.window makeKeyAndVisible];包含:
      • 设置当前窗口为App的主窗口
      • 显示窗口
        • 显示窗口
        • 设置跟窗口的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添加到到窗口上面"
          那么,会显示"根控制器(vc)view的自定义frame"
          代码如下:
                self.window.rootViewController = vc; -- 设置window的根控制器
                -- 把窗口根控制的view添加到到窗口上面
                [self.window addSubview:self.window.rootViewController.view]; 
                self.window.hidden = NO;
      2.2 直接写self.window.hidden = NO; 没写"把窗口根控制的view添加到到窗口上面"的代码, 
          会显示窗口,也会显示根控制器的view, "但不是自定义view的frame"。
          说明 self.window.hidden = NO; 
          后期还是会"把窗口根控制的view添加到到窗口上面"
          并且设置跟"窗口的frame一样的根控制view的frame"
          代码如下: 
                self.window.rootViewController = vc; 
                self.window.hidden = NO;
    
  • 效果图:

获取设置窗口

  • [UIApplication shareApplication].windows //本应用中打开的UIWindow列表
  • [UIApplication shareApplication].keyWindows // 主窗口
  • - (void) makeKeyWindow; 让当前UIWindow变成keyWindow(主窗口)
  • view.window 获得某个UIView所在的UiWindow

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。