I'm working on my own alert implementation and for that I created AlertViewController
.
My AlertViewController
contains actions (buttons) and textFields. To add actions I use the following method:
func addAction(title: String, handler: (() -> Void)? = nil) -> Self {
let button = UIButton()
button.setTitle(title, for: .normal)
button.setTitleColor(.label, for: .normal)
if let handler = handler {
button.addAction(handler)
}
actionsStackView.addArrangedSubview(button)
return self
}
I use the following extension to be able to add a closure as an action on a UIButton (find here):
@objc class ClosureSleeve: NSObject {
let closure: () -> Void
init (_ closure: @escaping () -> Void) {
self.closure = closure
}
@objc func invoke () {
closure()
}
}
extension UIButton {
func addAction(for controlEvents: UIControl.Event = .touchUpInside, _ closure: @escaping () -> Void) {
let sleeve = ClosureSleeve(closure)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
objc_setAssociatedObject(self, "[\(arc4random())]", sleeve, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
I would like to be able to retrieve the textFields from my AlertViewController
from a call to addAction
in the following way:
AlertViewController(title: "Information")
.addAction(title: "Send") { textFields in
let text = textFields?.first?.text
}
.show(on: self)
When I do this I got the following error: Contextual closure type '() -> Void' expects 0 arguments, but 1 was used in closure body
I don't know how to do it at all, I looked on the internet without success because I don't know what to look for.
Edit: I have create a gist with the code of my AlertViewController
here