Swift无Storyboard场景下关闭控制器后显示新控制器如何实现?
问题原因
你的代码存在3个核心问题:
- 你在SecondVC的按钮点击方法里手动初始化的
FirstViewController()是全新实例,不是当前已经在视图栈中的原始FirstVC,这个新实例没有关联当前的导航控制器,执行跳转方法自然不会生效。 - 跳转逻辑执行顺序错误,你在调用dismiss的同时就执行跳转,此时dismiss动画还没完成,上下文状态不对会导致跳转失效。
- 你表述要「模态弹出SecondVC」但使用了
navigationController.show()方法,该方法在导航控制器上下文下默认是push压栈操作,模态弹出应该用present(_:animated:completion:)。
正确实现方案
我们采用闭包回调的方式实现,逻辑简单易维护,适合新手使用:
步骤1:在SecondVC中定义回调属性
在SecondViewController类的顶部声明回调闭包:
class SecondViewController: UIViewController { // 认证完成后的回调闭包 var authFinishHandler: (() -> Void)? // 其他原有代码... }
步骤2:修改FirstVC弹出SecondVC的逻辑
在FirstVC中弹出SecondVC时,给它的回调属性赋值,用来处理后续跳转ThirdVC的逻辑:
// FirstViewController中登录按钮的点击代码 let secondVC = SecondViewController() secondVC.authFinishHandler = { [weak self] in guard let self = self else { return } let thirdVC = ThirdViewController() // 根据你的需求选择push或者模态弹出ThirdVC self.navigationController?.show(thirdVC, sender: self) } // 如果你要模态弹出SecondVC,替换为下面这行代码 // self.present(secondVC, animated: true) // 如果你要push压栈弹出SecondVC,保留原来的show写法 self.navigationController?.show(secondVC, sender: self)
步骤3:修改SecondVC的Auth按钮点击逻辑
点击按钮后先执行关闭操作,关闭完成后再调用回调触发FirstVC的跳转逻辑:
func buttonTapped() { // 如果是模态弹出的SecondVC,用dismiss关闭 self.dismiss(animated: true) { [weak self] in self?.authFinishHandler?() } // 如果是push压栈打开的SecondVC,用pop关闭,替换上面的代码为下面这段 /* self.navigationController?.popViewController(animated: true, completion: { [weak self] in self?.authFinishHandler?() }) */ }
补充说明
如果你的项目最低支持iOS13以下,popViewController没有自带的completion回调,可以用CATransaction来监听动画完成,代码如下:
CATransaction.begin() CATransaction.setCompletionBlock { self.authFinishHandler?() } self.navigationController?.popViewController(animated: true) CATransaction.commit()
内容的提问来源于stack exchange,提问作者Resly34
相关产品推荐
相关产品推荐

