You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 05:27:04