【问题标题】:Autorotation bug in iOS 13iOS 13 中的自动旋转错误
【发布时间】:2020-01-16 23:42:50
【问题描述】:

iOS 13/13.1 自动旋转的行为似乎与 iOS 12 不同。例如,我的应用允许用户在设置中将界面方向锁定为纵向或横向模式。

  1. 如果我在设备上设置了纵向旋转锁定并在 supportInterfaceOrientations 中返回 .landscape,则界面将保持纵向模式,直到我在设备上禁用纵向锁定方向。 iOS 12 似乎并非如此。事实上,在 iOS 13 中甚至都没有调用supportedInterfaceOrientations!

  2. UIViewController.attemptRotationToDeviceOrientation() 在这种情况下也不起作用。

问题的根源是我在应用程序初始化时暂时将 shouldAutorotate 返回为 false,当一切都初始化时,我调用 UIViewController.attemptRotationToDeviceOrientation() 来触发自动旋转。它在 iOS 12 中触发自动旋转,但在 iOS 13.1 中它不起作用。

看起来可能是 iOS 13.1 中的一个错误。如何强制触发自动旋转?

编辑:看起来 iOS 12.4.1 也忽略了 UIViewController.attemptRotationToDeviceOrientation()。 iOS 12.4.1 及更高版本的自动旋转出现问题。

说清楚,这就是我想要的:

一个。即使在 iPhone 上设置了纵向锁定,我希望我的界面在需要时自动旋转到横向模式,

b. UIViewController.attemptRotationToDeviceOrientation() 在所有情况下触发自动旋转的替代方案。

【问题讨论】:

  • supportedInterfaceOrientations 如果显示视图控制器将不会被调用。它会在全屏呈现时调用,但默认情况下,iOS 13 的 UIModalpresentationStyle 不是全屏的。

标签: ios swift uiviewcontroller autolayout autorotate


【解决方案1】:

试试这个,看看这是不是你要找的东西:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

    }

    @IBAction func btnLandscapeClicked(_ sender: Any) {
        let value = UIInterfaceOrientation.landscapeLeft.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
    }

    @IBAction func btnPortraitClicked(_ sender: Any) {
        let value = UIInterfaceOrientation.portrait.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
    }

}

extension UINavigationController {

    override open var shouldAutorotate: Bool {
        get {
            if let visibleVC = visibleViewController {
                return visibleVC.shouldAutorotate
            }
            return super.shouldAutorotate
        }
    }

    override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
        get {
            if let visibleVC = visibleViewController {
                return visibleVC.preferredInterfaceOrientationForPresentation
            }
            return super.preferredInterfaceOrientationForPresentation
        }
    }

    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
        get {
            if let visibleVC = visibleViewController {
                return visibleVC.supportedInterfaceOrientations
            }
            return super.supportedInterfaceOrientations
        }
    }}

【讨论】:

  • 嗯,这不是 hack 还是未记录的 API?
  • 而且我没有任何导航控制器
  • @DeepakSharma 这些都是 iOS SDK 可用的 API。我建议您将 ViewControllers 放在 NavigationController 中,即使您不使用它,也可以在屏幕上获得相同的行为。
【解决方案2】:

从 iOS 12.4.1 开始,应将视图控制器设置为全屏以尊重自动旋转方向。

let vc = UIViewController()
vc.modalPresentationStyle = .fullScreen
self.present(vc, animated: true, completion: nil)

【讨论】:

  • 模态显示在哪里出现我想知道,控制器没有模态显示。
  • 好吧..然后将您的导航控制器设置为全屏并在调用视图上的尝试设备旋转加载时返回不同的支持界面旋转。
  • 这为我解决了。我也在调用present,但由于呈现的 ViewController 具有不同的preferredInterfaceOrientationForPresentation,因此默认情况下它呈现为模态,也许这是一些 iOS 13 的行为?无论如何,谢谢,这很容易添加。
【解决方案3】:

回复其他面临此问题的人,这对我有用。转到项目设置 General > Deployment Info 并确保您已选中“Requires full screen”设置。

然后在 viewDidLoad 块之后粘贴以下代码:

// Forbid autorotate
override open var shouldAutorotate: Bool {
   return false
}

// Specify the orientation
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .landscape
}

【讨论】:

    最近更新 更多