如何在performSegue的sender参数中传递闭包?
在UIKit中用Segue传递闭包处理模态返回逻辑
当然可以!你完全可以利用performSegue的sender参数传递闭包,这样就能在用户退出模态页面后,优雅地执行你想要的后续操作,完美解决performSegue立即返回导致的逻辑分散问题。下面是具体的实现步骤和代码示例:
1. 定义闭包类型
首先在你的源ViewController里,定义一个符合需求的闭包类型,用来处理用户返回的结果。比如如果是接收用户的文本回答,可以这样写:
// 源ViewController(比如MainViewController)中 typealias AnswerCompletion = (String?) -> Void
这里用可选类型的参数,是为了区分用户提交了回答还是取消了操作(取消时传nil)。
2. 执行Segue时传递闭包
调用performSegue的时候,把你的闭包作为sender参数传进去。记得用[weak self]避免循环引用:
// 源ViewController中触发Segue的方法 func showQuestionDialog() { performSegue(withIdentifier: "ShowQuestionSegue", sender: { [weak self] answer in guard let self = self else { return } // 这里写用户返回后的逻辑 if let userAnswer = answer { print("用户提交的回答:\(userAnswer)") self.handleUserAnswer(userAnswer) // 比如更新UI或发起网络请求 } else { print("用户取消了提问") self.handleCancel() } } as AnswerCompletion) }
3. 在prepare方法中转递闭包给目标VC
在源ViewController的prepare(for:sender:)方法里,把sender转成我们定义的闭包类型,然后赋值给目标模态VC的属性:
// 源ViewController中 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "ShowQuestionSegue", let questionVC = segue.destination as? QuestionViewController, let completion = sender as? AnswerCompletion { // 将闭包传递给目标VC questionVC.completion = completion } }
4. 在目标VC中触发闭包
在你的模态QuestionViewController里,先添加一个闭包属性,然后在用户提交回答或取消时,调用这个闭包并dismiss页面:
// 目标ViewController(QuestionViewController)中 class QuestionViewController: UIViewController { // 定义接收的闭包属性 var completion: AnswerCompletion? // 假设你有输入框和按钮 @IBOutlet weak var answerTextField: UITextField! // 提交按钮点击事件 @IBAction func submitTapped(_ sender: UIButton) { let userAnswer = answerTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) completion?(userAnswer) dismiss(animated: true) } // 取消按钮点击事件 @IBAction func cancelTapped(_ sender: UIButton) { completion?(nil) dismiss(animated: true) } }
注意事项
- 避免循环引用:一定要在闭包中使用
[weak self],因为目标VC会持有闭包,如果闭包捕获了源VC的强引用,两个VC都会无法被释放,导致内存泄漏。 - 灵活扩展闭包参数:如果需要传递更多信息(比如用户选择的选项ID、布尔值等),可以修改
AnswerCompletion的参数类型,比如(Bool, Int) -> Void来适配你的业务需求。 - 闭包可选性:把目标VC的
completion声明为可选类型,避免没有传递闭包时出现崩溃。
内容的提问来源于stack exchange,提问作者ragnarius
相关产品推荐
相关产品推荐

