I'm expanding the functionality of [this SO answer][1]. [1]: http://stackoverflow.com/a/26454949/3804019 Mainly I'm focusing on: - You can add as many handlers as you want. - You can remove (i.e. cancel) the handler. - You can receive the `sender` parameter in the handler closure. - You can add "oneshot" handler. <!--- ---> import UIKit extension UIControl { private class EventHandler { let _cb: (UIControl, UIEvent) -> Void let _oneshot: Bool init(_ cb: (UIControl, UIEvent) -> Void, oneshot: Bool) { _cb = cb _oneshot = oneshot } @objc func invoke(sender: UIControl, event: UIEvent) { _cb(sender, event) if _oneshot { sender.off(unsafeAddressOf(self)) } } } typealias EventHandlerId = UnsafePointer<Void> func on<T: UIControl>(events: UIControlEvents, _ callback: (T, UIEvent) -> Void) -> EventHandlerId { assert(self.isKindOfClass(T), "The handler must receive \(NSStringFromClass(self.dynamicType)) or UIControl") return self._on(events, EventHandler({ callback($0 as T, $1) }, oneshot: false)) } func once<T: UIControl>(events: UIControlEvents, _ callback: (T, UIEvent) -> Void) -> EventHandlerId { assert(self.isKindOfClass(T), "The handler must receive \(NSStringFromClass(self.dynamicType)) or UIControl") return self._on(events, EventHandler({ callback($0 as T, $1) }, oneshot: true)) } func on(events: UIControlEvents, _ callback: () -> Void) -> EventHandlerId { return self._on(events, EventHandler({ _, _ in callback() }, oneshot: false)) } func once(events: UIControlEvents, _ callback: () -> Void) -> EventHandlerId { return self._on(events, EventHandler({ _, _ in callback() }, oneshot: true)) } private func _on(events: UIControlEvents, _ handler: EventHandler) -> EventHandlerId { let ptr = unsafeAddressOf(handler) self.addTarget(handler, action: "invoke:event:", forControlEvents: events) objc_setAssociatedObject(self, ptr, handler, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)) return ptr } func off(identifier: EventHandlerId) { if let handler = objc_getAssociatedObject(self, identifier) as? EventHandler { self.removeTarget(handler, action: nil, forControlEvents: .AllEvents) objc_setAssociatedObject(self, identifier, nil, 0) } } } Usage: class MyViewController:UIViewController { @IBOutlet weak var myButton:UIButton! override func viewDidLoad() { super.viewDidLoad() // add event handler let handle = myButton.on(.TouchUpInside) { (sender, event) in // `sender` is the control itself. // `event` is the UIEvent object. } // remove event handler myButton.off(handle) // event handler can be () -> Void type myButton.on(.TouchUpInside) { [unowned self] in // your work } // "oneshot" event handler myButton.once(.TouchUpInside) { // your work } } } It's working OK... But, for example: let btn = UIButton() btn.on(.TouchUpInside) { (sender: UISwitch, _) in /* ... */ } ^^^^^^^^ This compiles, but I want to make this compile time error. Currently, as a workaround, I'm doing "assertion": assert(self.isKindOfClass(T), "The handler must receive \(NSStringFromClass(self.dynamicType)) or UIControl") And, if possible, I wish the compiler could infer the type of the `sender`, like this: let btn = UIButton() btn.on(.TouchUpInside) { sender, _ in sender.titleLabel.text = "Pushed !!" } Any ideas?