• UIWindows简介



    UIWindow是一种特殊的UIView,通常在一个程序中只会有一个UIWindow,但可以手动创建多个UIWindow,同时加到程序里面。UIWindow在程序中主要起到三个作用:

    1. 作为容器,包含app所要显示的所有视图
    2. 传递触摸消息到程序中view和其他对象
    3. 与UIViewController协同工作,方便完成设备方向旋转的支持

    1. 看一下UIwindow的文档:

    NOTE

    1. 当使用 storyboard 时,已经自动帮你创建Windows对象了
    2. 当你使用 Interface Builder 时,需要在Launch option中设置全屏( Full Screen )选项
    3. 和创建UIView不同,UIWindow一旦被创建,它就自动地被添加到整个界面上了(UIWindow实例没能正常显示的原因是因为Window的hidden默认值为true,或者level不够高)

    Configuring Windows

    • @property(nonatomic) UIWindowLevel windowLevel
      • UIWindow在显示的时候会根据UIWindowLevel进行排序的,即Level高的将排在所有Level比他低的层级的前面。
      • 默认为 0.0
      • 还有三个特殊值:
        • UIKIT_EXTERN const UIWindowLevel UIWindowLevelNormal; 0.000000
        • UIKIT_EXTERN const UIWindowLevel UIWindowLevelAlert; 2000.000000
        • UIKIT_EXTERN const UIWindowLevel UIWindowLevelStatusBar __TVOS_PROHIBITED; 1000.000000
    • @property(nonatomic, strong) UIScreen *screen
      • 显示当前Window的UIScreen对象
      • 默认一般只有唯一的设备屏幕 (mac可以外接显示器,手机行吗?)
    • @property(nonatomic, strong) UIViewController *rootViewController
      • 默认为nil,(代码创建 或者使用 interface builder都可以为它赋值)
      • 若当前window已经保持了一个 view树,设置新值时,旧view树会被移除

    Making Windows Key

    • @property(nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow
      • 判断该windows是否是应用的keyWindow
      • keyWindow 能接收键盘或者其他 non-touch相关事件
      • 只有一个windows能作为keywindow
    • - (void)makeKeyAndVisible
      • 使Window成为 key windows,并且在相同或者低level之前展示
    • - (void)becomeKeyWindow
      • 当window成为 key window 时,该方法会被调用
      • 同时会发送 UIWindowDidBecomeKeyNotification 到默认通知中心
      • 不要自己直接调用这个方法
    • - (void)makeKeyWindow
    • - (void)resignKeyWindow
      • 与 becomeKeyWindow 相对应,当window让出 keywindow 时会被调用
      • 会发送 UIWindowDidResignKeyNotification 到默认通知中心

    Converting Coordinates

    // 跳过
    

    Sending Events

    • - (void)sendEvent:(UIEvent *)event
      • UIApplication 对象将分派事件 发送到相应的views ?

    2. 获取UIwindow

    2.1获取UIWindow列表

    [UIApplication sharedApplication].windows  
    

    获取在应用中打开的UIWindow列表,可以获取应用中的任何一个UIView对象,例如 当输入文字时,弹出的键盘就是UIWindow,如果需要改变键盘的样式,则可用更改当前Window

    2.2获取当前主窗口

    [UIApplication sharedApplication].keyWindow
    

    获取应用程序的主窗口,用来接收键盘以及非触摸类的消息事件的UIWindow,而且程序中每个时刻只能有一个UIWindow是keyWindow。

    注意:如果UIWindow内部的文本框不能输入文字,可能是因为这个UIWindow不是keyWindow

    2.3获取当前view 所在的UIWindow

    view.window
    

    获得某个UIView所在的UIWindow

    3. 把view添加到uiwindow

    创建一个控制器,把view添加到uiwindow上面(有两种方式)

    1. 直接将控制器的view添加到UIWindow中,并不理会它对应的控制器

       [self.window  addsubview:vc.view];
      
    2. 设置uiwindow的根控制器,自动将rootviewcontroller的view添加到window中,负责管理rootviewcontroller的生命周期

       [self.window.rootviewcontroller=vc];
      

    3.1两个方法的区别:

    以后的开发中,建议使用(2).因为方法(1)存在一些问题,比如说控制器上面可能由按钮,需要监听按钮的点击事件,如果是1,那么按钮的事件应该由控制器来进行管理。但控制器是一个局部变量,控制器此时已经不存在了,但是控制器的view还在,此时有可能会报错。注意:方法执行完,这个控制器就已经不存在了。

    问题描述1:当view发生一些事件的时候,通知控制器,但是控制器已经销毁了,所以可能出现未知的错误。

    问题描述2:添加一个开关按钮,让屏幕360度旋转(两者的效果不一样)。当发生屏幕旋转事件的时候,UIapplication对象会将旋转事件传递给uiwindow,uiwindow又会将旋转事件传递给它的根控制器,由根控制器决定是否需要旋转

    UIapplication->uiwindow->根控制器(第一种方式没有根控制器,所以不能跟着旋转)。

    提示:不通过控制器的view也可以做开发,但是在实际开发中,不要这么做,不要直接把view添加到UIWindow上面去。因为,难以管理

    4. 那么在哪些场合会涉及到“手工创建UIWindow”呢?

    参考唐巧在《iOS开发进阶》里的描述,我认为支付宝钱包等App的密码保护页面是基于UIWindow实现的,当用户从应用的任何界面按Home键退出,过一段时间再从后台切换回来时,显示一个密码输入界面。只有用户输入了正确的密码,才能进入退出前的界面。因为这个密码输入界面可能从任何应用界面弹出,并且需要盖住所有界面的最上层,所以很合适做一个UIWindow来实现。

    其他适合用UIWindow来实现的功能还包括:应用的启动介绍页,应用内的通知提醒消息,应用内的弹出框广告等。

    5.在有storyboard的项目中,UIWindow是如何创建的?

    有storyboard的项目中的创建过程:

    当用户点击应用程序图标的时候,先执行Main函数,执行UIApplicationMain(),根据其第三个和第四个参数创建Application,创建代理,并且把代理设置给application(看项目配置文件info.plist里面的storyboard的name,根据这个name找到对应的storyboard),开启一个事件循环,当程序加载完毕,

    他会调用代理的didFinishLaunchingWithOptions:方法。在调用didFinishLaunchingWithOptions:方法之前,会加载storyboard,在加载的时候创建一个window,接下来会创建箭头所指向的控制器,把该控制器设置为UIWindow的根控制器,接下来再将window显示出来,即看到了运行后显示的界面。(提示:关于这部分可以查看story的初始化的文档)

  • 相关阅读:
    php 显示文件 与Windows文件名排序一致
    pip3 install uwsgi 报错
    centos7 安装mysql 5.7
    Win7 开始菜单搜索添加快捷方式
    centos7.7 clamav 查杀病毒
    CentOS7.x 默认php版本与php7.4共存
    centos6.5 yum安装redis
    centos6 yum安装mysql 5.6 (完整版)
    解决phpmyadmin出现: Maximum execution time of 300
    Castle Windsor 使MVC Controller能够使用依赖注入
  • 原文地址:https://www.cnblogs.com/sunyanyan/p/5440074.html
Copyright © 2020-2023  润新知