iOS 16部分视图横竖屏切换异常问题求助
iOS 16 屏幕旋转适配问题解决方案
问题分析
iOS 16 对屏幕旋转的控制逻辑做了调整,原 AppDelegate 中的 supportedInterfaceOrientationsFor 方法在 iOS 16+ 版本中被弃用,系统优先读取 UIWindowSceneDelegate 中的对应配置。同时,视图控制器的旋转配置需要配合新的 API 调用时机,否则会出现进入视图时先横屏再切换竖屏的异常。
解决方案
1. 迁移旋转控制到 SceneDelegate
在 SceneDelegate 中实现 windowScene(_:supportedInterfaceOrientationsFor:) 方法,替代原 AppDelegate 中的逻辑:
func windowScene(_ windowScene: UIWindowScene, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { let presentedVC = window?.rootViewController?.presentedViewController if presentedVC is UIImagePickerController { return [.portrait, .landscapeRight] } if presentedVC is ChatPhotoPageContainerViewController { return .all } return .landscape }
2. 配置需要竖屏的视图控制器
在目标视图控制器中重写旋转相关属性,并在合适时机请求几何更新:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait // 根据需求设置为需要的竖屏方向 } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return .portrait } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 提前在视图即将显示时请求旋转,避免界面闪烁 guard let windowScene = view.window?.windowScene else { return } windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: supportedInterfaceOrientations)) { error in print("旋转请求失败: \(error.localizedDescription)") } }
3. 处理容器控制器的旋转传递
如果目标视图控制器被导航控制器、标签栏控制器等容器包裹,需要自定义容器控制器,将旋转设置传递给子控制器:
class CustomNavigationController: UINavigationController { override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return topViewController?.supportedInterfaceOrientations ?? .landscape } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return topViewController?.preferredInterfaceOrientationForPresentation ?? .landscapeLeft } }
4. 检查 Info.plist 配置
确保 Info.plist 中 UISupportedInterfaceOrientations 包含应用所需的所有方向,比如在全局横屏基础上添加竖屏:
<key>UISupportedInterfaceOrientations</key> <array> <string>UIInterfaceOrientationLandscapeLeft</string> <string>UIInterfaceOrientationLandscapeRight</string> <string>UIInterfaceOrientationPortrait</string> </array>
关键说明
- iOS 16 后,系统不再优先读取 AppDelegate 中的旋转配置,必须在 SceneDelegate 中实现对应方法。
requestGeometryUpdate需要在viewWillAppear中调用,提前触发旋转请求,避免进入视图后再切换方向的闪烁问题。- 容器控制器会默认覆盖子控制器的旋转设置,因此必须自定义容器并传递子控制器的配置。
内容的提问来源于stack exchange,提问作者Yura Geyts
相关产品推荐
相关产品推荐

