Swift中Segue执行条件设置及prepare函数调用问题
看起来你把Segue的准备逻辑完全放错地方啦!你现在把prepare(for:sender:)嵌套在自定义的stateCondition函数里,这根本行不通——因为prepare(for:sender:)是UIViewController的系统生命周期方法,必须直接在ViewController类里重写(override),系统才会在Segue触发时自动调用它,嵌套在其他函数里系统根本找不到这个方法。
下面一步步给你修正逻辑:
第一步:把判断逻辑放在按钮点击事件里,手动控制Segue触发
首先你得把「检查文本框是否为空」的逻辑,直接写在按钮的点击IBAction里,通过条件判断决定是否触发Segue:
@IBAction func triggerButtonTapped(_ sender: UIButton) { // 先校验所有必填内容是否合法 guard let ageText = ageTextField.text, !ageText.isEmpty, let genderText = genderTextField.text, !genderText.isEmpty, let bmiText = bmiLabel.text, !bmiText.isEmpty else { // 有空内容,弹出警告弹窗 let alert = UIAlertController(title: "提示", message: "请填写完整信息后重试", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) present(alert, animated: true) return } // 所有内容合法,手动触发指定Segue performSegue(withIdentifier: "popUp", sender: self) }
这里用guard做安全校验,确保所有需要的内容都不为空,避免后续强制解包崩溃。如果校验不通过,直接弹出警告并终止流程;校验通过就调用performSegue手动触发Segue。
第二步:正确重写prepare函数,处理数据传递
把你原来嵌套在stateCondition里的prepare逻辑,移到ViewController类的顶层,作为override方法:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // 处理"popUp" Segue的数据传递 if segue.identifier == "popUp" { // 安全转换目标控制器+解析数据,避免强制解包崩溃 guard let popUpVC = segue.destination as? PopUpViewController, let ageText = ageTextField.text, let age = Double(ageText), let genderText = genderTextField.text, let bmiText = bmiLabel.text, let bmi = Double(bmiText) else { return } // 给弹出视图控制器赋值 popUpVC.age = age popUpVC.gender = genderText popUpVC.bmi = bmi print("Segue准备完成,数据已传递") } // 如果还有其他Segue(比如你提到的"info"),可以在这里继续处理 if segue.identifier == "info" { _ = segue.destination as! InfoViewController // 这里可以添加info Segue的逻辑 } }
同样用guard做安全校验,比你原来的强制解包!要稳妥得多,能避免因为文本内容不是数字导致的崩溃。
第三步:移除错误的stateCondition函数
你原来的stateCondition函数完全没必要保留,因为判断逻辑已经整合到按钮点击事件里,prepare函数也已经正确重写了。
额外提醒
如果你的Storyboard里是直接把Segue绑定到按钮上的,也可以通过重写shouldPerformSegue(withIdentifier:sender:)来做条件拦截,但手动调用performSegue的方式逻辑更直观,适合你的场景。
内容的提问来源于stack exchange,提问作者Arika Afrin Boshra

