iPhone开启竖屏方向锁定时如何强制App特定页面自动横屏
不需要依赖CoreMotion即可实现该效果,不受系统竖屏方向锁定限制,核心是通过应用级的方向配置强制触发界面旋转,你的现有代码只需要补充几个缺失的配置即可生效:
第一步:配置AppDelegate基础能力
首先确保AppDelegate中已经声明方向锁属性,并实现系统方向代理方法:
@main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? // 全局方向锁属性 var orientationLock: UIInterfaceOrientationMask = .portrait func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return orientationLock } }
第二步:修复导航控制器的方向适配优先级
默认情况下iOS会优先读取导航控制器的方向配置,而非子控制器的配置,需要补充UINavigationController的扩展:
extension UINavigationController { open override var supportedInterfaceOrientations: UIInterfaceOrientationMask { // 优先使用当前顶层子控制器的方向配置 return topViewController?.supportedInterfaceOrientations ?? .portrait } open override var shouldAutorotate: Bool { return topViewController?.shouldAutorotate ?? true } }
第三步:给目标横屏控制器配置单独的方向规则
在你需要自动横屏的ViewController中重写方向属性:
class PlayViewController: UIViewController { // 仅支持横屏 override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .landscape } // 允许自动旋转 override var shouldAutorotate: Bool { return true } // 返回时切回竖屏 override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) AppUtility.lockOrientation(.portrait, andRotateTo: .portrait) } }
第四步:兼容新旧系统优化转屏工具类
你的原工具类逻辑没有问题,补充iOS16+的官方API兼容,避免私有API的潜在风险:
struct AppUtility { static func lockOrientation(_ orientation: UIInterfaceOrientationMask) { if let delegate = UIApplication.shared.delegate as? AppDelegate { delegate.orientationLock = orientation } } static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) { self.lockOrientation(orientation) if #available(iOS 16.0, *) { UIApplication.shared.connectedScenes .compactMap { $0 as? UIWindowScene } .forEach { windowScene in windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: orientation)) windowScene.keyWindow?.rootViewController?.setNeedsUpdateOfSupportedInterfaceOrientations() } } else { UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation") UINavigationController.attemptRotationToDeviceOrientation() } } }
调用方式
在跳转进入横屏控制器之前,先调用转屏方法触发旋转即可:
// 跳转前先设置强制横屏 AppUtility.lockOrientation(.landscape, andRotateTo: .landscapeLeft) let playVC = PlayViewController() navigationController?.pushViewController(playVC, animated: true)
以上方案完全不受系统方向锁定的影响,进入播放页会自动切换为横屏,返回时自动切回竖屏,和Prime Video的实现逻辑一致。
内容的提问来源于stack exchange,提问作者Yuuu
相关产品推荐
相关产品推荐

