iOS Swift4(Xcode9)无导航控制器下跨VC跳转并指定返回路径的方案
嗨,针对你的需求,我整理了两个适配Xcode9、Swift4环境的可行方案,都能满足「从C移除自身和B后展示D,返回直接到A」的要求,同时复用D已实现的平滑转场逻辑,完全不用UINavigationController:
方案一:层级追溯+转场后清理(推荐,视觉连贯性最好)
这个方案的核心是让A成为D的presentingViewController,同时让D的转场动画从C的界面发起,转场完成后悄悄清理掉B和C的层级,用户完全感知不到中间的层级变化。
实现步骤:
- 在C视图控制器中,向上追溯找到A的实例:
// 从C的presentingViewController拿到B,再从B的presentingViewController拿到A guard let bVC = self.presentingViewController, let aVC = bVC.presentingViewController else { print("无法找到A视图控制器") return }
- 初始化D并配置转场参数(复用D已实现的
UIViewControllerTransitioningDelegate):
let dVC = DViewController() dVC.transitioningDelegate = dVC // 假设D自身作为转场代理(如果你的代理是单独对象,替换成对应的实例即可) dVC.modalPresentationStyle = .custom // 自定义转场必须设置这个样式 // 可选:给D传递C的视图作为转场起始参考(如果你的转场动画需要基于起始位置计算) // 需要在D中新增一个UIView?类型的属性,比如var transitionSourceView: UIView? dVC.transitionSourceView = self.view
- 让A present D,转场完成后清理B和C:
aVC.present(dVC, animated: true) { // 转场完成后无动画dismiss B和C,用户看不到这个操作 bVC.dismiss(animated: false) }
为什么这样可行?
- D的转场动画完全复用你已经实现的逻辑,视觉上是从C平滑过渡到D;
- 转场完成后B和C被移除,此时D的
presentingViewController是A,所以从D返回时,调用self.dismiss(animated: true)会直接回到A。
方案二:直接Dismiss到A再Present D(简化版,连贯性稍弱)
如果你的转场动画对起始视图没有严格要求,这个方案逻辑更简单,只是会先看到回到A的动画,再看到进入D的动画:
实现步骤:
- 同样先找到A的实例:
guard let bVC = self.presentingViewController, let aVC = bVC.presentingViewController else { return }
- 先将B和C一起dismiss回到A,在完成回调中让A present D:
// 调用A的dismiss方法会一次性移除所有它之上的presented视图控制器(也就是B和C) aVC.dismiss(animated: true) { let dVC = DViewController() dVC.transitioningDelegate = dVC dVC.modalPresentationStyle = .custom aVC.present(dVC, animated: true) }
注意事项:
- 确保D的
UIViewControllerTransitioningDelegate实现了必要的方法:animationController(forPresented:presenting:source:)(处理present转场)和animationController(forDismissed:)(处理dismiss转场),否则无法触发平滑转场; - 如果方案一中的转场不需要起始视图参考,可以省略传递
transitionSourceView的步骤。
内容的提问来源于stack exchange,提问作者Bhanuka Yd
相关产品推荐
相关产品推荐

