advantis
9/24/2014 - 9:04 AM

C#-inspired event handling in Swift

C#-inspired event handling in Swift

class ViewController: UIViewController {

    @IBOutlet
    weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        button.TouchUpInside += action

        button.TouchUpInside += {sender in
            println("closure: \(sender)")
        }
    }

    func action(sender: AnyObject) {
        println("method: = \(sender)")
    }
}
extension UIControl {
    struct ControlEvents {
        static let TouchUpInside = "TouchUpInside"
    }

    var TouchUpInside: Event {
        return objc_getAssociatedObject(self, ControlEvents.TouchUpInside) as Event! ?? {
            let event = Event()
            self.addTarget(event, action: "invoke:", forControlEvents:UIControlEvents.TouchUpInside)
            objc_setAssociatedObject(self, ControlEvents.TouchUpInside, event, UInt(OBJC_ASSOCIATION_RETAIN))
            return event
        }()
    }
}
typealias EventHandler = (AnyObject) -> Void

class Event {
    var handlers: [EventHandler] = []

    func subscribe(handler: EventHandler) {
        handlers.append(handler)
    }

    dynamic func invoke(sender: AnyObject) {
        handlers.map({$0(sender)})
    }
}

func +=(event: Event, handler: EventHandler) {
    event.subscribe(handler)
}