iOS 17中横屏跳转竖屏锁定页面出现两次跳转问题排查
iOS 17横屏跳转竖屏页面触发两次跳转问题排查与解决方案
问题原因分析
- iOS 17调整了屏幕旋转的生命周期回调逻辑:从横屏页面跳转至锁定竖屏的页面时,系统先触发一次跳转,随后强制竖屏的配置会触发屏幕旋转,而iOS 17中该旋转动作会意外重新触发跳转逻辑——低版本iOS里旋转不会关联跳转事件的二次触发。
- 跳转逻辑未做版本适配:如果跳转代码依赖
viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)这类屏幕旋转相关生命周期方法,iOS 17中该方法的调用时机、次数和低版本不一致,会导致跳转代码被重复执行。 - 导航栈处理存在差异:iOS 17的
UINavigationController在处理屏幕旋转后的页面栈时,存在偶发的重复入栈逻辑,直接导致跳转动作被执行两次。
是否可解决及修复方案
该问题可解决,以下是几种可行修复方式:
- 添加跳转状态锁:在跳转方法中增加布尔型状态标记(如
isNavigating),跳转前判断标记状态,跳转开始后设为true,跳转完成(比如在viewDidAppear中)再重置为false,避免重复触发。示例代码:
private var isNavigating = false @IBAction func jumpToPortraitVC(_ sender: UIButton) { guard !isNavigating else { return } isNavigating = true let portraitVC = PortraitViewController() navigationController?.pushViewController(portraitVC, animated: true) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) isNavigating = false }
- 适配iOS 17屏幕旋转逻辑:在目标竖屏页面的
supportedInterfaceOrientations方法中明确锁定方向,同时在源横屏页面里,避免在屏幕旋转回调中触发跳转逻辑;若必须关联,增加版本判断:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) if #available(iOS 17, *) { // iOS 17下跳过跳转相关逻辑 return } // 低版本原有逻辑 }
- 用导航控制器代理拦截重复跳转:实现
UINavigationControllerDelegate的navigationController(_:willShow:animated:)方法,判断即将显示的控制器是否已在栈顶,避免重复入栈。
内容的提问来源于stack exchange,提问作者Sugumaran
相关产品推荐
相关产品推荐

