Check Boxes in AppKit

Check boxes in AppKit are realized with buttons. The API reads kind of weird, because the NSButton.state property does so many things, so here’s a simple subclass I do sometimes employ:

class Checkbox: NSButton {    
    var isChecked: Bool {
        get { state == .on }
        set { state = newValue ? .on : .off }
    }
}

Now it’s easy to use checkbox.isChecked = true.

I’d even consider check() and uncheck() commands if I used this in many places to reduce the noise and clarify what’s going on further, maybe.

If the subclass feels like the wrong abstraction, that’s a fair point; it’s still a button, really, so the new type name doesn’t add much. So for a smaller footprint, I’m exposing the isChecked property on NSButton itself:

extension NSButton {    
    var isChecked: Bool {
        get { state == .on }
        set { state = newValue ? .on : .off }
    }
}

An alternate name would be isOn or isToggled, because apart from check boxes, there’s also radio buttons (for which “is checked” still kinda works), switches, and depressable toggle buttons.

Why even bother?

This adds a KeyPath<NSButton, Bool> (more or less a lens) that you can use elsewhere, e.g. in binding to conditions directly without having to carry the ternary operator around with you.