传递变量通过 Segue 返回的对象,具体取决于按下的按钮



我有一个WorkoutGenerator结构,它根据不同的参数返回不同的锻炼,例如generateWorkout.standardWorkout返回与generateWorkout.hardWorkout不同的内容。

我在"锻炼设置"页面上有 3 个按钮,每个按钮都旨在将不同类型的锻炼传递到"锻炼页面"(还有一个"锻炼时间"的输入字段)。

我目前有一个从"锻炼设置页面"到"锻炼页面"的续集goToWorkout

我想做的是触发对锻炼页面的segue,根据用户按下的内容传递不同的锻炼。

到目前为止,我有:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//currently have one segue between the pages
if segue.identifier == "goToWorkout" {
let finalTimeForWorkout = Int(timeInputField.text!)              
//set a standardWorkout to pass to Workout Page
let finalWorkout = FinalWorkout(generatedWorkout: WorkoutGenerator.standardWorkout.generate(), timeForWorkout: finalTimeForWorkout!)
//set the final parameters ready to pass
let finalWorkoutTime = finalWorkout.timeForWorkout
let finalWorkoutExercises = finalWorkout.generatedWorkout.workoutExercises
if let destVC = segue.destination as? WorkoutController {
destVC.selectedWorkoutExerciseArray = finalWorkoutExercises
destVC.selectedWorkoutTime = finalWorkoutTime
}
}
}  
and then something like this for each button :
//use this button to pass a standard workout
//want to pass a diff workout if a diff button pressed
@IBAction func standardWorkoutPressed(_ sender: UIButton) {
performSegue(withIdentifier: "goToWorkout", sender: self )
}

玩了几个小时后,我的问题是如何将不同的锻炼优雅传递到锻炼页面。

即我想我可以从字面上复制并粘贴每个按钮的所有代码,并为每个按钮制作一个新的 segue,但这似乎是错误的方法!

我尝试过的那种事情是将锻炼定义为ifelse if部分中的变量,但最终的锻炼超出了 segue 的范围。

希望这是有道理的,我可以找到的关于条件 segue 的答案似乎主要是指"只允许在这种情况下发生 segue",而不是将不同的数据集传递到同一个目的地。 例如示例 1 和示例 2

我将添加我的注释作为答案,以便更轻松地显示一些代码示例。

向视图控制器添加属性:

var selectedWorkout : FinalWorkout!

在三个按钮操作方法中的每个方法中,将此属性设置为与每个按钮关联的锻炼。因此,对于您的标准锻炼:

@IBAction func standardWorkoutPressed(_ sender: UIButton) {
let finalTimeForWorkout = Int(timeInputField.text!)
self.selectedWorkout = FinalWorkout(generatedWorkout: WorkoutGenerator.standardWorkout.generate(), timeForWorkout: finalTimeForWorkout!)
performSegue(withIdentifier: "goToWorkout", sender: self )
}

最后:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToWorkout" {
let finalWorkoutTime = selectedWorkout.timeForWorkout
let finalWorkoutExercises = selectedWorkout.generatedWorkout.workoutExercises
if let destVC = segue.destination as? WorkoutController {
destVC.selectedWorkoutExerciseArray = finalWorkoutExercises
destVC.selectedWorkoutTime = finalWorkoutTime
}
}
}

performSegue(withIdentifier:sender:)中,sender可以是任何你喜欢的东西。

使用sender将生成的锻炼传递给performSegue

//use this button to pass a standard workout
//want to pass a diff workout if a diff button pressed
@IBAction func standardWorkoutPressed(_ sender: UIButton) {
performSegue(withIdentifier: "goToWorkout", sender: WorkoutGenerator.standardWorkout.generate() )
}

然后在prepare(for:sender:)

let finalWorkout = FinalWorkout(generatedWorkout: sender as! YourWorkoutGeneratorType, timeForWorkout: finalTimeForWorkout!)

如果我有这个权利,你想根据按下的按钮将不同的参数传递到你的FinalWorkout()函数中吗?

它并不总是提供非常可读的代码,但您可以使用 UIButtontag属性。如果您将每个按钮的标签属性设置为唯一值 [0, 1, 2],则可以使用该信息生成不同的体训练:

// This code would be in: override func prepare(for segue: UIStoryboardSegue, sender: Any?)
let buttonTag = (sender as! UIButton).tag
if buttonTag == 0 { // Generate type of workout}
else if buttonTag == 1 { // Generate type of workout }
else if buttonTag == 2 { // Generate type of workout }

或者,如果您担心标签不是直观的表示形式,您可以只测试每个按钮的IBOutlet参考的相等性:

let buttonPressed = sender as! UIButton
if (buttonPressed == self.yourButtonIBOutletPropertyName) { // select a workout for this button} 

我可能错过了你的问题,如果这是案例评论,我会更新答案。

最新更新