如何通过Segue根据点击按钮传递不同Workout数据至目标页面?
优雅解决Segue传递不同训练内容的方案
你遇到的问题其实很常见——复用同一个Segue但传递不同数据,完全不用新增Segue或者复制粘贴代码,利用performSegue的sender参数就能优雅解决,同时避开作用域问题。下面是具体的实现步骤:
1. 定义训练类型枚举
先创建一个枚举来明确所有训练类型,让代码更清晰易维护:
enum WorkoutType { case standard, hard, custom // 第三个类型根据你的实际需求命名 }
2. 修改按钮的IBAction方法
把每个按钮对应的训练类型作为sender传递给performSegue,而不是传self:
@IBAction func standardWorkoutPressed(_ sender: UIButton) { performSegue(withIdentifier: "goToWorkout", sender: WorkoutType.standard) } @IBAction func hardWorkoutPressed(_ sender: UIButton) { performSegue(withIdentifier: "goToWorkout", sender: WorkoutType.hard) } @IBAction func customWorkoutPressed(_ sender: UIButton) { performSegue(withIdentifier: "goToWorkout", sender: WorkoutType.custom) }
3. 重构prepare方法
现在在prepare方法里,我们可以直接从sender拿到训练类型,安全处理输入参数,然后生成对应训练内容:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // 先做安全校验:Segue标识正确、sender是训练类型、时间输入有效 guard segue.identifier == "goToWorkout", let workoutType = sender as? WorkoutType, let timeText = timeInputField.text, let finalTimeForWorkout = Int(timeText) else { // 如果输入无效,给用户提示 let alert = UIAlertController(title: "输入错误", message: "请输入有效的训练时长", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) present(alert, animated: true) return } // 根据训练类型生成对应的训练内容 let generatedWorkout: GeneratedWorkout // 这里替换成你实际的训练生成结果类型 switch workoutType { case .standard: generatedWorkout = WorkoutGenerator.standardWorkout.generate() case .hard: generatedWorkout = WorkoutGenerator.hardWorkout.generate() case .custom: generatedWorkout = WorkoutGenerator.customWorkout.generate() // 替换成你的第三个训练方法 } // 组装最终要传递的训练数据 let finalWorkout = FinalWorkout(generatedWorkout: generatedWorkout, timeForWorkout: finalTimeForWorkout) // 传递给目标控制器 if let destVC = segue.destination as? WorkoutController { destVC.selectedWorkoutExerciseArray = finalWorkout.generatedWorkout.workoutExercises destVC.selectedWorkoutTime = finalWorkout.timeForWorkout } }
为什么这个方案优雅?
- 无冗余代码:只用一个Segue,不用复制多份prepare逻辑或者新增Segue
- 作用域清晰:所有逻辑都在prepare方法内完成,变量作用域合理
- 可扩展性强:以后要加新的训练类型,只需要在枚举里加case,新增按钮的IBAction传递对应的类型即可
- 安全可靠:用可选绑定替代强制解包,避免输入无效导致崩溃,还加了用户提示
内容的提问来源于stack exchange,提问作者nc14
相关产品推荐
相关产品推荐

