iOS16+仅单屏横屏展示UIViewController失效问题(Swift5.7)
iOS 16 竖屏应用中单独展示横屏界面的UIWindow适配方案
问题背景
在iOS 16之前,整个应用仅支持竖屏模式时,通过重写ViewController的以下三个属性即可实现单独展示横屏界面:
override public var shouldAutorotate: Bool { return false } override public var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .landscapeLeft } override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return .landscapeLeft }
但iOS 16后这套逻辑失效,且现有公开方案多基于UIWindowScene,现提供基于UIWindow的适配方案。
适配代码实现
1. 横屏ViewController核心代码
在需要横屏展示的ViewController中,保留原有旋转属性的同时,新增iOS 16专属的界面几何更新逻辑:
import UIKit class LandscapeViewController: UIViewController { // 保留iOS 16之前的旋转控制逻辑 override public var shouldAutorotate: Bool { return false } override public var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .landscapeLeft } override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return .landscapeLeft } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // iOS 16及以上版本,通过windowScene请求旋转 if #available(iOS 16.0, *) { guard let windowScene = view.window?.windowScene else { return } let orientationPrefs = UIWindowScene.GeometryPreferences.Orientation( supportedOrientations: .landscapeLeft ) windowScene.requestGeometryUpdate(orientationPrefs) { error in if let error = error { print("横屏切换失败:\(error.localizedDescription)") } } } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 退出时恢复应用竖屏状态 if #available(iOS 16.0, *) { guard let windowScene = view.window?.windowScene else { return } let orientationPrefs = UIWindowScene.GeometryPreferences.Orientation( supportedOrientations: .portrait ) windowScene.requestGeometryUpdate(orientationPrefs) } } }
2. 全局竖屏配置
确保整个应用默认仅支持竖屏,可通过两种方式设置:
- Info.plist配置:添加
Supported interface orientations字段,仅保留Portrait (bottom home button)选项。 - AppDelegate配置(适用于UIWindow架构):
@main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return .portrait } }
注意事项
- 若使用Storyboard或XIB展示该ViewController,需确保其布局适配横屏尺寸;
- 调用
requestGeometryUpdate时需确保ViewController的view已关联到window,故放在viewDidAppear中执行更稳妥; - 退出横屏界面时必须恢复竖屏,避免影响后续界面的方向状态。
内容的提问来源于stack exchange,提问作者Chetan Prajapati
相关产品推荐
相关产品推荐

