如何从VC B直接dismiss至RootViewController且不显示中间控制器?
直接从Present层级的VC B回到RootVC且不显示中间VC A的解决方法
这个问题我之前开发时也踩过坑!当你用present一层层弹出控制器时,系统默认的dismiss会按层级从上到下逐个执行,所以从VC B回到RootVC时,会先闪过VC A再回到根控制器。下面有几个简单有效的方案:
方案一:两步Dismiss(推荐,符合系统动画逻辑)
思路是先带动画让VC B消失,再在完成回调里无动画地关掉VC A,这样用户完全看不到中间的VC A:
// 在VC B中调用 self.dismiss(animated: true) { // 获取VC B的上一级控制器(VC A),无动画dismiss它 self.presentingViewController?.dismiss(animated: false, completion: nil) }
原理:第一个dismiss是正常的带动画操作,用户看到VC B按预期消失;完成后,在后台无动画地移除VC A,直接回到RootVC,整个过程看不到VC A的身影。
方案二:直接重置RootViewController(适合需要自定义过渡动画的场景)
如果想要更灵活的过渡效果,可以直接替换window的根控制器,同时模拟dismiss的动画:
guard let window = UIApplication.shared.keyWindow, let rootVC = window.rootViewController else { return } // 用过渡动画切换回根控制器 UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: { window.rootViewController = rootVC }, completion: { _ in // 清理所有残留的presented控制器 rootVC.dismiss(animated: false, completion: nil) })
你可以把options换成比如.transitionFlipFromLeft之类的自定义过渡效果,但这个方法本质是重置根控制器,和系统默认的dismiss动画略有不同,按需选择。
为什么你的原有方法会显示VC A?
当你调用rootViewController?.dismiss(animated: true)时,系统会递归处理所有presented的控制器:先让VC A dismiss它的presented控制器(VC B),动画完成后,再让RootVC dismiss VC A。这个过程中VC A会短暂显示,所以你能看到它闪过。
内容的提问来源于stack exchange,提问作者KevinVuD
相关产品推荐
相关产品推荐

