Swift4:无NavigationController时dismiss当前控制器并显示新控制器报错求助
问题分析与解决方案
首先,你的代码里有两个关键问题导致了这个错误,我们一步步来拆解:
错误原因
self.storyboard可能失效:当你在dismiss的completion闭包里使用self.storyboard时,当前视图控制器已经被dismiss,它的storyboard引用大概率已经变成nil,自然找不到对应的故事板去实例化新VC。- 错误的present逻辑:你写了
vc!.present(vc!, animated: true, completion: nil)——这是让新实例化的VC去present它自己,完全不符合iOS视图控制器的层级规则,这本身就会引发崩溃,更别说找不到VC的问题了。
修复后的代码
我们需要找到弹出当前VC的那个控制器(也就是presentingViewController),让它在当前VC被dismiss后去present新的VC,同时用安全解包避免强制解包的风险:
@IBAction func go_back_btn_pressed(_ sender: UIButton) { // 先获取弹出当前VC的父控制器,确保它存在 guard let presentingVC = self.presentingViewController else { print("无法找到弹出当前页面的控制器") return } self.dismiss(animated: true) { // 在当前页面消失后,让父控制器实例化并展示新页面 // 如果你的目标VC不在当前故事板,需要替换成对应的故事板名称,比如UIStoryboard(name: "OtherStoryboard", bundle: nil) if let targetVC = presentingVC.storyboard?.instantiateViewController(withIdentifier: "goOrders") { presentingVC.present(targetVC, animated: true, completion: nil) } else { print("故事板中找不到标识符为 `goOrders` 的视图控制器") } } }
额外排查步骤
如果还是出现找不到VC的错误,请检查以下几点:
- 打开你的Storyboard,找到目标视图控制器,确认它的Storyboard ID确实设置为
goOrders(注意Swift是大小写敏感的,不要写错大小写)。 - 如果目标VC在另一个独立的Storyboard文件里,不要用
presentingVC.storyboard,而是直接指定故事板名称:let storyboard = UIStoryboard(name: "你的故事板名称", bundle: nil) if let targetVC = storyboard.instantiateViewController(withIdentifier: "goOrders") { // ... } - 永远避免使用强制解包
!,用if let或guard let来安全处理可选值,防止因为nil导致的崩溃。
内容的提问来源于stack exchange,提问作者Sarwar Jahan
相关产品推荐
相关产品推荐

