根据按下的按钮,通过 Segue 传递变量返回的对象

Pass variable returned Object via Segue depending on which button pressed

我有一个 WorkoutGenerator 结构,它 returns 基于不同参数的不同训练,例如 generateWorkout.standardWorkout returns 与 generateWorkout.hardWorkout 不同的东西。

我在 'Workout Setup' 页面上有 3 个按钮,每个按钮用于将不同类型的锻炼传递给 'Workout Page'('workout time' 也有一个输入字段)。

我目前有一个 segue goToWorkout 从 "Workout Setup Page" 到 "Workout Page"

我想做的是触发 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,但这似乎是错误的方法!

我尝试过的事情是将训练定义为 if else if 部分中的变量,但最终训练超出了 segue 的范围。

希望这是有道理的,我能找到的关于条件 segues 的答案似乎主要是指 'only allow the segue to happen under this condition' 而不是将不同的数据集传递到同一目的地。例如example1 and example2

我将添加我的评论作为答案,以便更容易显示一些代码示例。

将 属性 添加到您的 viewcontroller:

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() 函数传递不同的参数吗?

它并不总能生成非常易读的代码,但您可以使用 UIButton tag 属性。如果您将每个按钮的标签 属性 设置为唯一值 [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} 

我可能漏掉了你的问题,如果是这种情况请评论,我会更新答案。