Swift 5如何通过闭包将函数作为参数传入UIAlertController自定义扩展
问题解答
问题1:调用方式是否正确?
不正确,存在两个核心错误:
- 你创建了全局的
UIAlertController实例actionView,并在它上面调用present方法弹出新的ActionSheet。但present要求调用者本身处于当前活跃的控制器栈中,这个全局实例从未被加载展示,根本无法完成弹出操作。 - 该工具方法的定位不合理,ActionSheet本身是由当前业务控制器弹出的,你完全可以把这个方法扩展到
UIViewController上,不需要依附于无用的UIAlertController实例。
问题2:闭包传参的正确写法
首先你原来的方法定义里参数类型写错了:operation1:()代表参数是Void空值,不是可执行的闭包。你需要先把方法的参数改成逃逸闭包类型@escaping () -> Void,因为闭包会在用户点击按钮时延迟执行,需要逃逸出方法作用域。
1. 调用时的参数传递修正
你原来的写法operation1:deleteEvent()是直接执行了deleteEvent方法,把返回的空值传给了参数,会导致一调用action方法就执行删除逻辑,不等用户点击按钮。
正确写法(注意加[weak self]避免循环引用):
action(mes: "delete ",tit: "Delete only",tit2: "Delete All ", operation1: { [weak self] in self?.deleteEvent() }, operation2: { [weak self] in self?.deleteEvent(deleteAll: true) })
如果方法没有参数,也可以直接传函数名:operation1: deleteEvent
2. ActionSheet handler中的闭包调用修正
你只需要在handler里执行传入的闭包即可,正确写法:
let EButton = UIAlertAction(title:tit , style: .default, handler: { _ in operation1() // 加括号执行闭包 })
完整修正后的代码参考
工具扩展部分
import UIKit // 扩展到UIViewController更合理,所有VC都可以直接调用 extension UIViewController { func showCustomActionSheet(mes: String, tit: String, tit2: String, operation1: @escaping () -> Void, operation2: @escaping () -> Void) { let actionSheet = UIAlertController(title: "", message: mes, preferredStyle: .actionSheet) let firstAction = UIAlertAction(title: tit, style: .default, handler: { _ in operation1() }) let secondAction = UIAlertAction(title: tit2, style: .default, handler:{ _ in operation2() }) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil) // 统一设置按钮颜色 [firstAction, secondAction, cancelAction].forEach { $0.setValue(UIColor.red, forKey: "titleTextColor") } actionSheet.addAction(firstAction) actionSheet.addAction(secondAction) actionSheet.addAction(cancelAction) // 当前VC直接弹出 present(actionSheet, animated: true, completion: nil) } }
业务控制器调用部分
class ViewControllerA: UIViewController { // 你的业务方法 func saveEvent() { // 保存逻辑 } func deleteEvent(deleteAll: Bool = false) { // 删除逻辑 } } private extension ViewControllerA { func alertBottomSheet() { showCustomActionSheet(mes: "Update", tit: "Update only", tit2: "Update All", operation1: { [weak self] in self?.saveEvent() }, operation2: { [weak self] in self?.saveEvent() }) } @IBAction func deleteEventButtonClicked(_ sender: Any) { showCustomActionSheet(mes: "delete ", tit: "Delete only", tit2: "Delete All ", operation1: { [weak self] in self?.deleteEvent() }, operation2: { [weak self] in self?.deleteEvent(deleteAll: true) }) } }
内容的提问来源于stack exchange,提问作者getc
相关产品推荐
相关产品推荐

