如何在performSegue的sender参数中传递闭包?

时间:2019-06-19 10:47:02

标签: ios swift modal-dialog closures segue

在我的 iOS 应用中,我想问用户一个问题,然后根据答案采取一些措施。

在许多其他编程框架中,我会使用模式对话框,等待用户输入结果,然后将结果返回到主代码。但是,据我所知,UIKit框架不包含此类模式对话框。取而代之的是,我使用模式 segue ,但是由于对performSegue的调用会立即返回,因此编程变得有些混乱……

performSegue的发送者参数类型为Any?。我可以使用该参数传递 closure 以及用户退出segue时要执行的代码吗?而且,如果是这样,怎么办?

2 个答案:

答案 0 :(得分:1)

我认为performSegue不可能做到这一点,但是您可以在执行segue时使用prepareForSegue发送值。

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {        
    let vc = segue.destination as! MyViewController
    vc.myParameter = myValue

}

但是,如果您只是想给用户一个对话框并等待答案,那么还有另一种方法。

您可以使用默认背景制作一个viewController,将其隐藏,然后在其中添加一个View并对其进行自定义,您可以将其视为Alert。然后在您要询问用户数据时启动它。

let vc = self.storyboard?.instantiateViewController(withIdentifier: "alert") as! AlertViewController
vc.definesPresentationContext = true
vc.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
//Here you can pass data into the viewController you're initiating
vc.myParameter = myValue
self.present(vc,animated: false,completion: nil)

这样,您在viewController中自定义的UIView就会像在当前viewController上发出普通警报一样显示。

答案 1 :(得分:0)

在撰写本文时,该问题有3票否定!我不明白为什么。我认为我的问题已明确陈述。

可以使用performSegueprepare(for:sender:)。但是使用instantiateViewController需要较少的设置工作。

这是基于Yasser答案的解决方案

在情节提要中,我创建了一个视图控制器PawnPromotionVC),该视图控制器具有半透明的白色背景视图和一个不透明的较小子视图,其中包含“对话框”。视图控制器具有一个声明为onExit的属性,如下所示:

   var onExit : ((Piece) -> Void)?

下面是该视图控制器中用于按钮轻击的动作处理程序(顺便说一下,“对话框”的目的是询问用户将棋子提升到哪个棋子):

  @IBAction func pieceButtonTapped(_ sender: UIButton) {
        let piece = Piece(rawValue: sender.tag)!

        if let run = onExit {
            run( piece )
        }
        dismiss(animated: true, completion: nil)
    }

要启动我调用的对话框

  if ... {
      runPawnPromotionDialog(){
          (piece:Piece) in
           print("the pawn should be promoted to a \(piece)" )
           ...
           ...
      }
  }

来自我的 mainViewController 。同样在mainViewController中实现的功能runPawnPromotionDialog几乎按照Yasser的建议实现:

  func runPawnPromotionDialog( onExit: @escaping (Piece) -> Void ){

        let vc = self.storyboard?.instantiateViewController(withIdentifier: "PawnPromotionVC") as! PawnPromotionVC

        vc.definesPresentationContext = true
        vc.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
        vc.modalTransitionStyle = .crossDissolve

        vc.onExit = onExit
        self.present(vc,animated: false,completion: nil)
    }