UIScreen和UIWindow

  1. UIScreen 和UIWindow

    UIScreen object defines the properties associated with a hardware-based display

    就是说UIScreen是硬件显示器的软件表示。通过UIScreen来获取和设置对应显示器的属性。一个设备可以有一个主屏幕和若干附属屏幕(attached screens)。

    A UIWindow object provides the backdrop for your app’s user interface and provides important event-handling behaviors

    UIWindow是用户界面的载体,用户的输入首先被对应的UIWindow接收,然后被转发到其他的view上。

  2. UIScreen和UIWindow的关系

    • 一个UIWindow必须有一个UIScreen,否者这个屏幕就是黑色的。
    • 一个UIScreen可以有多个UIWindow。一个app只能有一个keywindow
  3. UIWindow

  • windowLevel
    UIWindow分布在z轴的不同位置。前面的UIWindow会遮住后面的UIWindow。如果同一个level有多个UIWindow,这些window之间的顺序是不确定的。
    系统定义的windowlevel

    • UIWindowLevelNormal
    • UIWindowLevelStatusBar
    • UIWindowLevelAlert
  • rootViewController: UIViewController
    每一个window必须设置rootviewcontroller。这个rootviewcontroller的view就是window要显示的内容。

  • screen: UIScreen
    这个window要在哪个屏幕上展示。一个window只能在一个屏幕上展示。

  • keywindow

    A window is considered the key window when it is currently receiving keyboard and non touch-related events.

    就是说如果一个window可以接收键盘和非触摸事件,那么这个就叫做keywindow。

    • 事件响应流是这样的。
      • 如果一个触摸了屏幕,那么这个事件会被分配到响应的UIWindow上,然后由UIWindow来做事件分发。
      • 如果一个事件没有对应的坐标呢,就被keywindow来做响应的分发和处理。
    • 如何判断一个window是不是keywindow?
      isKeyWindow: Bool { get }
    • 如何把一个window变成keywindow
      • 调用makeKeyAndVisible()方法。调用这个方法会把这个window变成keywindow,并在同级别的level中在最前面展示。因此,keywindow不一定显示在最前面,可能在z轴方向上有一个window在keywindow上面。
        若想把一个window变成可见的,只需要设置hidden属性为no就好了。
        // Show the window, but do not make it key
        self.externalWindow!.hidden = false
   - 调用`makeKey() `方法。这个方法不改变window的可见性。
  • keywindow的生命周期
    1. 成为keywindow
      发送UIWindowDidBecomeKey通知,调用becomeKey()方法
    2. 变得可见
      发送UIWindowDidBecomeVisible方法。
    3. 变得不可见
      发送UIWindowDidBecomeHidden方法
    4. 放弃成为keywindow
      发送UIWindowDidResignKey通知,调用resignKey()方法
  1. UIScreen
  • 获取主屏幕
    class func main() -> UIScreen
  • 获取所有屏幕
    class func screens() -> [UIScreen]。mainScreen永远是第一个。
  • 获取屏幕分辨率
    • var bounds: CGRect { get }。 考虑到了屏幕的旋转,point表示。
    • var nativeBounds: CGRect { get }。以像素衡量的分辨率,不考虑旋转。
    • 获取屏幕的point衡量的分辨率。
      UIScreen.mainScreen().fixedCoordinateSpace.bounds
    • 另一种获取考虑屏幕旋转的point表示的分辨率的方法
      UIScreen.mainScreen().coordinateSpace.bounds
    • nativeScalescale
      无论是CoreGraphics还是图片scale选取,都应该以[UIScreen scale]为准。
    • 设置屏幕的亮度
      var brightness: CGFloat { get set }。范围是0到1,1最亮。下次锁屏之前一直有效。如果锁屏然后解锁,恢复到系统亮度。
    • 屏幕刷新时的回调
      let ca1 = UIScreen.mainScreen().displayLinkWithTarget(self, selector: #selector(ViewController.testCADisplay))
      ca1?.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
- 相关通知
  - 有屏幕连接
  UIScreenDidConnect
  - 有屏幕断开连接
UIScreenDidDisconnect
  - 屏幕分辨率变化

UIScreenModeDidChange
- 屏幕亮度变化
UIScreenBrightnessDidChange

  1. 相关参考资料
  • 处理iPhone6、6+标准视图和放大视图 & 新增的[UIScreen nativeScale]方法
  • Wrong image scale for iPhone 6+ Zoomed in mode #2830
  • Using multiple UIWindows in iOS applications

你可能感兴趣的:(UIScreen和UIWindow)