【问题标题】:prepareForSegue and PerformSegueWithIdentifier senderprepareForSegue 和 PerformSegueWithIdentifier 发件人
【发布时间】:2016-10-15 20:46:05
【问题描述】:

我想知道标题中的函数是如何工作的,也想知道 sender 参数。

假设单击按钮调用 performSegue 方法,那是否也调用 prepareSegue 方法? prepareSegue 方法是在 performSegue 方法之前调用但在按钮按下之后调用的吗?

另外,两个函数中的“sender”参数是否相关联?如果我在 performSegue 方法中传入一个字符串作为发送者,那会转移到 prepareSegue 方法中的发送者参数吗?换句话说,如果我将 performSegue 方法中的 sender 参数设置为“Hi world”,那么 prepareSegue 方法中的 sender 参数也会是同一个字符串吗?

谢谢

【问题讨论】:

    标签: ios swift iphone storyboard segue


    【解决方案1】:

    实际上,有两种方法可以触发 segue。第一个是通过对 Interface Builder 中的 UI 元素的操作,第二个是在您的代码中使用 performSegueWithIdentifier:sender:。我说'有效',因为在幕后,当从情节提要加载场景时,会配置一个动作处理程序,最终调用performSegueWithIdentifier:sender:

    performSegueWithIdentifier:sender: 被调用时,segue 对象被传递给你的视图控制器的prepareForSegue:sender: 函数。

    如果 segue 由 UI 元素上的操作启动,则发送者将是该 UI 元素(即,如果它是 UIButton 上的操作连接,则 sender 将是 UIButton实例)。

    如果 segue 是由您的代码调用 performSegueWithIdentifier:sender: 启动的,那么 sender 将是您作为 sender 传递的任何对象。这可能是您的视图控制器、按钮、数组或任何东西。所以是的,如果您将“Hello World”作为sender 值传递给performSegueWithIdentifier:sender:,那么这将是prepareForSegue:sender: 中的sender

    就操作顺序而言:

    1. performSegueWithIdentifier:sender 被您的代码或作为对 UI 元素的操作的结果调用
    2. 如果您的视图控制器实现了shouldPerformSegueWithIdentifier:sender:,则调用此函数。如果此函数返回false,则取消转场
    3. segue 对象和目标视图控制器对象已创建
    4. 如果您的视图控制器实现了prepareForSegue:sender:,则调用此函数。
    5. 一旦prepareForSegue:sender: 返回,segue 就完成了。

    【讨论】:

    • 谢谢你,它为我节省了一点回溯——我需要知道 prepareForSegue 是否仍然会被独立于检查 shouldPerformSegue 的返回值而被调用。
    • 在 UIKit 中,发送者通常是视图或视图控制器,因为它被内部机制使用,如 targetViewControllerForAction:sender: 和 canPerformAction:sender: 如果你使用自定义对象作为发送者那么它会搞砸的。
    • 文档说明没有这样的限制,处理performSegueWithIdentifier:sender时不会调用targetViewControllerForAction:SendercanPerformAction:sender
    • 对于内置的表演和表演细节故事板 segue 模板。观看此 WWDC 视频 developer.apple.com/videos/play/wwdc2014/216 或此链接 optshiftk.com/2014/08/… 中的 31 分钟
    • UISplitViewController 的 showViewController 使用内部方法 _childContainingSender,其中发送者必须是 UIView 或 UIViewController,因此它可以使用方法 _isMemberOfViewControllerHierarchy: 这是其自适应性的一部分。
    【解决方案2】:

    performSegue 方法调用要从一个视图执行到另一个视图的 segue。在 segue 实际发生之前,调用 prepareForSegue 方法,如果你想在视图之间传递数据,你会在那里做。

    performSegue 方法不接受您要发送的参数。它仅用于首先调用segue。您要发送的任何数据都将通过 prepareForSegue 完成。

    这是一个例子。

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Do any additional setup after loading the view.
    
        performSegueWithIdentifier("test", sender: self)
        //You can set the identifier in the storyboard, by clicking on the segue
    }
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "test"{
            var vc = segue.destinationViewController as! RandomViewController
            vc.data = "Data you want to pass"
            //Data has to be a variable name in your RandomViewController
        }
    }
    

    如果这有帮助,请告诉我!

    【讨论】:

    • 您可以在performSegueWithIdentifier:sender: 中以sender 的形式传递要发送的数据,但您需要将其传输到prepareForSegue:sender: 中的目标视图控制器
    • 美丽。谢谢。
    • 试过了,不行。在第二个 ViewController 中获得零。不知道为什么。
    • 使用 Swift 5 performSegue(withIdentifier: "showPartListViewController", sender: self)
    【解决方案3】:

    The_Curry_Man 的回答对我有用。这是他的 Swift 3 代码更新。

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    
        performSegue(withIdentifier: "test", sender: self)
        //You can set the identifier in the storyboard, by clicking on the segue
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "test"{
            var vc = segue.destinationViewController as! RandomViewController
            vc.data = "Data you want to pass"
            //Data has to be a variable name in your RandomViewController
        }
    }
    

    【讨论】:

      【解决方案4】:

      我给初学者的两分钱......在swift 3中是:

      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      
      }
      

      所以,如果到达控制器(MyController 类)实现了“fillData”方法:

      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      
          if let destController = segue.destination as MyController{
      
              destController.fillData(...)
          }
      
      }
      

      【讨论】:

        【解决方案5】:

        Swift 5 的更新方法

        performSegue(withIdentifier: "showNextViewController", sender: self)
        

        注意:“showNextViewController”是为故事板中的 segue 添加的标识符

        【讨论】:

          【解决方案6】:

          通过使用带有标识符的执行segue将任何对象发送到特定对象到另一个视图控制器时,请按照步骤#Swift4

          override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
              if segue.identifier == "Detailed_Live_poll"{
                  let destinationNavigationController = segue.destination as! UINavigationController
                  let targetController = destinationNavigationController.topViewController as! NewLivePollViewController
                  targetController.dictQuestInf = sender as! NSDictionary
              }
          }
          

          【讨论】:

          • 发件人参数不应用作传递数据的黑客手段。它需要是 UIView 或类似的 segue 才能正常工作。使用视图控制器上的属性来获取要在准备中使用的数据。
          猜你喜欢
          • 2013-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多