iOS Swift跨Storyboard通过Segue传值及导航控制器问题
看起来你在跨Storyboard跳转并传递数据时踩了个典型的坑——目标ProjectsListVC被嵌套在Navigation Controller里,但你同时混用了Storyboard Segue跳转和手动实例化VC两种方式,再加上Segue的连接可能没做对,才导致了要么提示Segue不存在、要么找不到VC的问题。下面给你两种清晰的解决方案,选一种适合你的就行:
方法一:使用Storyboard Segue跳转(推荐,符合Storyboard工作流)
这种方法需要你确保Storyboard里的Segue是正确连接的:
- 打开源Storyboard,从你的源ViewController直接拖线到目标Storyboard里的Navigation Controller(不是直接拖到
ProjectsListVC),设置Segue的identifier为toProjectsProd(和你代码里的一致)。 - 修改
prepare(for:sender:)方法,因为Segue的destination现在是Navigation Controller,你需要从它里面拿到真正的ProjectsListVC:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { guard segue.identifier == "toProjectsProd" else { return } // 先拿到跳转目标的Navigation Controller guard let navController = segue.destination as? UINavigationController else { print("无法转换为UINavigationController") return } // 从导航控制器中获取根ViewController也就是ProjectsListVC guard let projectsVC = navController.topViewController as? ProjectsListVC else { print("无法获取ProjectsListVC") return } // 传递数据 projectsVC.projectsSentT = ProjecctProd projectsVC.logedInAsT = "Prod" }
- 跳转的时候直接调用你原来的代码就行:
self.performSegue(withIdentifier: "toProjectsProd", sender: nil)
方法二:纯代码手动实例化跳转(不用Storyboard Segue)
如果不想用Storyboard里的Segue,完全用代码控制跳转,那你需要实例化的是Navigation Controller而不是直接实例化ProjectsListVC:
- 打开目标Storyboard(ProdProj.storyboard),给里面的Navigation Controller设置一个Storyboard ID(比如
ProjectsNavController,记得在Identity Inspector里设置)。 - 修改你的跳转代码:
// 加载目标Storyboard let storyboard = UIStoryboard(name: "ProdProj", bundle: nil) // 实例化Navigation Controller(用刚才设置的Storyboard ID) guard let navController = storyboard.instantiateViewController(withIdentifier: "ProjectsNavController") as? UINavigationController else { print("无法实例化Navigation Controller") return } // 从导航控制器中拿到ProjectsListVC guard let projectsVC = navController.topViewController as? ProjectsListVC else { print("无法获取ProjectsListVC") return } // 传递数据 projectsVC.projectsSentT = ProjecctProd projectsVC.logedInAsT = "Prod" // 执行跳转(如果当前VC在导航栈里用push,否则用present) if let currentNav = self.navigationController { currentNav.pushViewController(navController, animated: true) } else { self.present(navController, animated: true) }
关键注意点
- 不要同时混用
performSegue和手动实例化VC的方式,二者选其一,否则逻辑会混乱。 - 检查所有ID是否匹配:Segue的identifier、Navigation Controller的Storyboard ID、
ProjectsListVC的类名是否和代码里一致。 - 如果用Segue跳转,一定要确保Segue是连接到Navigation Controller,而不是直接连接到
ProjectsListVC,否则segue.destination会是VC本身,无法转换成导航控制器。
内容的提问来源于stack exchange,提问作者Tony Merritt
相关产品推荐
相关产品推荐

