iPhone和iPad设备之间的UIWindow方向不一致?

时间:2019-06-15 09:54:28

标签: ios uikit uiwindow

我正在尝试为覆盖行为创建自定义UIWindow,并且我到处都看到“ UIWindow并非基于方向”;女巫正是我想要的,因为我想匹配物理设备的边界。

在iPhone上,一切正常,UIWindow保持一致,并且我的行为仍然不错;旋转设备时边框不会移动: iPhone preview

在上面的iPad上,使用完全相同的代码,我在UIWindow层上获得了旋转动画(我用来绘制边框),这使这种奇怪的布局发生了: iPad preview

我不使用轮换通知;因为我不想回应轮换。我使用UIScreen nativeBounds的“非定向感知”范围来确保我没有定向敏感的对象。跨设备的这种不同行为使我感到困惑。

有人已经遇到过这种奇怪的行为吗?您如何回应? 有没有好的做法或解决方法?

项目的完整代码(包括示例应用程序)在此处: https://github.com/Dean151/RecordingOverlay

overlay和UIWindow子类的特定代码在这里: https://github.com/Dean151/RecordingOverlay/blob/master/Sources/RecordingOverlay/RecordingOverlay.swift

1 个答案:

答案 0 :(得分:0)

结果表明,如果满足某些条件,则窗口会自动旋转。当所有这些参数都满足时,我不得不覆盖旋转。

如果所有这些都成立,UIWindow将自动旋转:

  • iOS至少为9.0
  • 设备是iPad
  • 应用程序支持所有设备旋转
  • 应用程序使用情节提要作为其主界面(在info.plist中声明)
  • 应用程序不需要全屏显示(在info.plist中声明)

您可以使用一小段代码来检测到这一点:

@available(iOS 9.0, *)
var willAutorotate: Bool {
    guard UIDevice.current.userInterfaceIdiom == .pad else {
      return false
    }

    let window = UIApplication.shared.delegate?.window ?? nil
    guard UIApplication.shared.supportedInterfaceOrientations(for: window) == .all else {
        return false
    }

    let info = Bundle.main.infoDictionary ?? [:]
    guard info["UIRequiresFullScreen"] as? Bool != true else {
        return false
    }

    guard info["UILaunchStoryboardName"] != nil else {
        return false
    }

    return true
}

现在,我知道它何时会自动旋转,我可以更改帧和变换以“取消”旋转。