【问题标题】:Pass variable returned Object via Segue depending on which button pressed根据按下的按钮,通过 Segue 传递变量返回的对象
【发布时间】:2018-05-18 08:53:42
【问题描述】:

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

“锻炼设置”页面上有 3 个按钮,每个按钮用于将不同类型的锻炼传递到“锻炼页面”(还有一个“锻炼时间”输入字段)。

我目前有一个从“锻炼设置页面”到“锻炼页面”的 segue 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 的范围。

希望这是有道理的,我能找到的关于条件转场的答案似乎主要是指“只允许转场在这种情况下发生”,而不是将不同的数据集传递到同一个目的地。例如example1example2

【问题讨论】:

  • 我认为您知道点击按钮时用户选择了哪种锻炼方式?如果是这样,只需在点击按钮时将此锻炼存储在一个属性中,然后在执行 segue 时访问它,将其传递给目标视图控制器
  • 我只是快速浏览了一下,一些建议 - 当您询问一个非常通用的概念时,您的问题有很多特定于上下文的细节。我认为您可以将您的问题的长度和复杂度缩短四分之一。
  • 感谢@Peza,我会确保我以后这样做

标签: ios swift segue swift4 uistoryboardsegue


【解决方案1】:

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

将属性添加到您的视图控制器:

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
        }
    }
 }

【讨论】:

  • 此解决方案有效 - 但它会在一个屏幕上加载锻炼内容,然后立即加载另一个屏幕。当我点击标准时,第一个是正确的,而第二个是错误的,但当我点击“repeaterWorkout”时,情况正好相反——你知道为什么会这样吗?
  • 我有 2 个 segues 从按钮触发我的错!
【解决方案2】:

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!)

【讨论】:

    【解决方案3】:

    如果我有这个权利,您想根据按下的按钮向您的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} 
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-05
      相关资源
      最近更新 更多