如何在 performSegue 的 sender 参数中传递闭包?
How to pass a closure in performSegue's sender parameter?
在我的 iOS 应用程序中,我想问用户一个问题,然后根据答案采取一些行动。
在许多其他编程框架中,我会使用模式对话框等待用户输入结果,然后 returns 将结果发送到主代码。但是,据我所知,UIKit 框架不包含这样的 modal dialogs 。相反,我使用模态 segue,但由于立即调用 performSegue
returns,编程变得有些混乱......
performSegue
有一个类型为 Any?
的发件人参数。我可以使用该参数来传递 closure 以及用户退出 segue 时要执行的代码吗?如果是这样,怎么做到的?
我认为 performSegue
不可能,但您可以使用 prepareForSegue
在执行 segue 时发送值。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! MyViewController
vc.myParameter = myValue
}
但如果您只想给用户一个对话框并等待答案,还有另一种方法可以做到这一点。
你可以制作一个带有默认背景的viewController,这将使其隐藏,然后在其中添加一个视图并根据需要对其进行自定义,你可以将其视为一个警报。然后在你想向用户询问数据时启动它。
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 上的普通警报一样显示。
在撰写本文时,这个问题有三张反对票!我不明白为什么。在我看来,我的问题已经说得很清楚了。
可以使用 performSegue
和 prepare(for:sender:)
。但是使用 instantiateViewController
需要较少的设置工作。
这是一个解决方案基于 Yasser 的回答:
在情节提要中,我创建了一个 视图控制器 (PawnPromotionVC
),它有一个半透明的白色背景视图,以及一个包含 "dialog".视图控制器有一个 onExit
属性声明如下:
var onExit : ((Piece) -> Void)?
下面是那个视图控制器中按钮点击的动作处理程序(顺便说一下,"dialog" 的 objective 是询问用户一个 pawn 应该被提升到哪个棋子) :
@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。函数runPawnPromotionDialog
,也是在mainViewController中实现的,几乎按照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)
}
在我的 iOS 应用程序中,我想问用户一个问题,然后根据答案采取一些行动。
在许多其他编程框架中,我会使用模式对话框等待用户输入结果,然后 returns 将结果发送到主代码。但是,据我所知,UIKit 框架不包含这样的 modal dialogs 。相反,我使用模态 segue,但由于立即调用 performSegue
returns,编程变得有些混乱......
performSegue
有一个类型为 Any?
的发件人参数。我可以使用该参数来传递 closure 以及用户退出 segue 时要执行的代码吗?如果是这样,怎么做到的?
我认为 performSegue
不可能,但您可以使用 prepareForSegue
在执行 segue 时发送值。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! MyViewController
vc.myParameter = myValue
}
但如果您只想给用户一个对话框并等待答案,还有另一种方法可以做到这一点。
你可以制作一个带有默认背景的viewController,这将使其隐藏,然后在其中添加一个视图并根据需要对其进行自定义,你可以将其视为一个警报。然后在你想向用户询问数据时启动它。
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 上的普通警报一样显示。
在撰写本文时,这个问题有三张反对票!我不明白为什么。在我看来,我的问题已经说得很清楚了。
可以使用 performSegue
和 prepare(for:sender:)
。但是使用 instantiateViewController
需要较少的设置工作。
这是一个解决方案基于 Yasser 的回答:
在情节提要中,我创建了一个 视图控制器 (PawnPromotionVC
),它有一个半透明的白色背景视图,以及一个包含 "dialog".视图控制器有一个 onExit
属性声明如下:
var onExit : ((Piece) -> Void)?
下面是那个视图控制器中按钮点击的动作处理程序(顺便说一下,"dialog" 的 objective 是询问用户一个 pawn 应该被提升到哪个棋子) :
@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。函数runPawnPromotionDialog
,也是在mainViewController中实现的,几乎按照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)
}