自定义 class 以创建带有按钮的警报。如何添加完成处理程序?

Custom class to create an Alert with Buttons. How to add a completition handler?

我试图创建一个自定义警报,但我对在按钮上实现完成处理程序感到很生气。我尝试了一些方法,最后,创建 func 数组以传入 UIButton 的选择器 addTarget 函数,但没有用。 (****** 在哪里)

问题:"Argument of #selector does no refer to @obc method, property or initializer"

我不能做的困难的编码部分是用我从我的视图控制器收到的一些代码配置选择器,我在视图控制器中使用下面的 class 创建一个对象。

class Alert: NSObject {

func showAlert(){

    if let window = UIApplication.shared.keyWindow {

        //configure some constraints and animations
}

var buttons: [UIButton] = []
var buttonsFunc: [() -> Void ] = []


func addNewButton(title: String, handler: @escaping () -> Void) {
    buttons.append(createButton(title: title))

    buttonsFunc.append {
        self.dismissAlert()
        handler()
    }
}

func setupButtons() {

    for (index, button) in buttons.enumerated() {
        boxView.addSubview(button)

        //Here is the problem ***************************
        button.addTarget(self, action: #selector(buttonsFunc[index]), for: .touchUpInside)


        //More constraints(not important)
        button.centerXAnchor.constraint(equalTo: boxView.centerXAnchor).isActive = true
        button.widthAnchor.constraint(equalTo: (button.titleLabel?.widthAnchor)!).isActive = true
        button.heightAnchor.constraint(equalToConstant: 25).isActive = true
    }

}

func dismissAlert(){
   //Animation to dismiss my alert
}

其他功能:

//Even if its not important the function i use to create the button

 func createButton(title: String) -> UIButton {
    let button = UIButton(type: .system)
    button.backgroundColor = .clear
    button.setTitle(title, for: .normal)
    button.titleLabel?.sizeToFit()
    button.setTitleColor(uPBlue, for: .normal)
    button.titleLabel?.font = UIFont(name: uPFont, size: 20)
    button.translatesAutoresizingMaskIntoConstraints = false
    return button
}

有什么解决办法吗? 或者也许是一种完全不同的方式。 如果有用我就采纳

所以选择器只是一个函数的名称。根据定义,闭包是一个匿名函数,因此您不能完全这样做。

让我们尝试另一条路线,定义一个新功能给按钮:

private func buttonPressed(sender: UIButton) {

}

然后让我们给按钮这个功能而不是闭包:

...
button.addTarget(self, action: #selector(Alert.buttonPressed(sender:)), for: .touchUpInside)
...

现在我们可以在这里利用 tuples。我们将使用一个具有临时数据结构的数组来代替两个单独的数组 buttons:actions:

// var buttons: [UIButton] = []
// var buttonsFunc: [() -> Void ] = []
// Becomes
var buttonActionArray: [(button: UIButton, action: () -> Void)] = []

现在让我们实施 buttonPressed(sender:)

private func buttonPressed(sender: UIButton) {

   for buttonTuple in buttonActionArray {
      if buttonTuple.button === sender {
         buttonTuple.action()
      }
   }      
}