点击VC3按钮后如何Dismiss前两个模态VC并从VC1 Push VC4?
解决方案
核心要点是等待模态 dismissal 完成后再执行导航栈的 Push 操作,同时要正确定位到 VC1 所在的导航控制器。
Swift 实现代码
在 VC3 的按钮点击事件中添加如下逻辑:
@IBAction func goToVC4ButtonTapped(_ sender: UIButton) { // 先 dismiss 掉当前的 VC3 和上层的 VC2,回到 VC1 self.dismiss(animated: true) { [weak self] in // 安全获取 VC1 及其导航控制器 guard let vc2 = self?.presentingViewController, let vc1 = vc2.presentingViewController as? VC1, let navController = vc1.navigationController else { return } // 实例化 VC4 并执行 Push let vc4 = VC4() navController.pushViewController(vc4, animated: true) } }
Objective-C 实现代码
如果使用 Objective-C,对应逻辑如下:
- (IBAction)goToVC4ButtonTapped:(UIButton *)sender { [self dismissViewControllerAnimated:YES completion:^{ // 逐层获取到 VC1 UIViewController *vc2 = self.presentingViewController; VC1 *vc1 = (VC1 *)vc2.presentingViewController; UINavigationController *navController = vc1.navigationController; if (!navController) return; // Push 到 VC4 VC4 *vc4 = [[VC4 alloc] init]; [navController pushViewController:vc4 animated:YES]; }]; }
为什么之前的方法可能无效?
- 未等待 Dismiss 完成:如果在调用
dismiss后立即执行 Push,此时模态的 VC2/VC3 还未完全从视图层级移除,导航栈操作会被模态窗口遮挡或失效。必须在dismiss的completion回调中执行后续操作。 - 错误定位导航控制器:如果直接尝试从 VC3 获取导航控制器,会得到 nil(因为 VC3 不在导航栈中),必须通过
presentingViewController逐层向上找到 VC1,再获取它所属的导航控制器。
适配复杂层级的优化方案
如果后续页面层级可能变化,可以用递归方法动态查找目标 VC,避免硬编码层级:
private func findTargetVC<T: UIViewController>(type: T.Type, from currentVC: UIViewController?) -> T? { guard let vc = currentVC else { return nil } if let targetVC = vc as? T { return targetVC } return findTargetVC(type: type, from: vc.presentingViewController) }
在 Dismiss 回调中使用该方法:
self.dismiss(animated: true) { [weak self] in guard let vc1 = self?.findTargetVC(type: VC1.self, from: self), let navController = vc1.navigationController else { return } let vc4 = VC4() navController.pushViewController(vc4, animated: true) }
内容的提问来源于stack exchange,提问作者LULULULALLA
相关产品推荐
相关产品推荐

