How do I replace target/action with callbacks in Swift?

NSButton uses the target/action pattern: a button : NSButton has two properties button.target and button.action which specify what to call when the button is clicked.

This is rather different to the way I’m used to programming: I’d like to just set button.onClick = { ... do some stuff ... }. In short, this is how to do it:

class CallbackWrapper {
    var callback : () -> ();
    init(callback: @escaping () -> ()) {
        self.callback = callback;
    }
    @objc public func callCallback() {
        self.callback();
    }
}

func setTargetActionCallback(control: NSControl, callback: @escaping () -> ()) {
    let wrapper = CallbackWrapper(callback: callback);
    control.target = wrapper;
    control.action = #selector(CallbackWrapper.callCallback);
    let key = UnsafeMutablePointer<Int8>.allocate(capacity: 1);
    objc_setAssociatedObject(control, key, wrapper, .OBJC_ASSOCIATION_RETAIN);
}

Explanation:

Thanks to Mike Ash and Ham Chapman for finding that post.

Tagged #swift, #objective-c.

Similar posts

More by Jim

Want to build a fantastic product using LLMs? I work at Granola where we're building the future IDE for knowledge work. Come and work with us! Read more or get in touch!

This page copyright James Fisher 2016. Content is not associated with my employer. Found an error? Edit this page.