如何仅用UIKit同步视图控制器的present与push操作?
解决UIKit中Present动画期间Push操作静默失败的问题
核心思路是利用UIKit原生提供的视图控制器过渡协调器(UIViewControllerTransitionCoordinator)感知present动画状态,确保push操作在present动画完成后执行,全程无需自定义标记或依赖主应用额外逻辑。
实现方案
在框架发起push操作的代码中,先判断目标导航控制器的顶层视图控制器是否处于present动画过程中:若处于动画状态,则等待动画完成后再执行push;否则直接执行push。
Objective-C 代码示例
// 假设已获取到要执行push的导航控制器 navVC UIViewController *topVC = navVC.topViewController; if (topVC.transitionCoordinator && topVC.isBeingPresented) { // 等待present动画(含交互结束)完成后执行push [topVC.transitionCoordinator notifyWhenInteractionEndsUsingBlock:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { // 仅当present操作未被取消时执行push if (!context.isCancelled) { [navVC pushViewController:[[YellowViewController alloc] init] animated:YES]; } }]; } else { // 无正在进行的present动画,直接push [navVC pushViewController:[[YellowViewController alloc] init] animated:YES]; }
Swift 代码示例
// 假设已获取到要执行push的导航控制器 navVC guard let topVC = navVC.topViewController else { return } if let coordinator = topVC.transitionCoordinator, topVC.isBeingPresented { coordinator.notifyWhenInteractionEnds { context in guard !context.isCancelled else { return } navVC.pushViewController(YellowViewController(), animated: true) } } else { navVC.pushViewController(YellowViewController(), animated: true) }
方案说明
- 依赖UIKit原生状态:通过
isBeingPresented判断顶层VC是否正在被present,transitionCoordinator获取当前过渡协调器,均为UIViewController的原生公开属性,无需自定义任何标记。 - 安全处理动画场景:
notifyWhenInteractionEndsUsingBlock会在present动画(包括用户交互取消的场景)完全结束后触发回调,确保push操作在视图控制器层级稳定后执行,避免静默失败。 - 框架独立性:代码仅依赖UIKit公开API,不需要主应用提供额外逻辑或标记,完全符合框架与主应用分离的要求。
内容的提问来源于stack exchange,提问作者rojarand
相关产品推荐
相关产品推荐

