Disabling Segments in a NSSegmentedControl in a Toolbar
This post is part of a series on getting NSSegmentedControl
to work in your toolbars.
- Original Approach
- Enabling/Disabling Segments (this post)
- Fixing an action dispatching bug
- Fixing action dispatching within overflow menus
Earlier this week I posted how to create a segmented toolbar item with 1 label for each segment. Now some options in TableFlip depend on context: without a selected cell, you cannot remove the selection, for example. So I disabled some segments and it looked alright:
Easy enough:
let enabled = hasSelection()
ThisParticularSegmentedControl.contextualSegments // = (0...1)
.forEach { (segment: Int) in
self.setEnabled(enabled, forSegment: segment)
}
But even though it’s disabled, and even though the NSSegmentedControl
’s trackingMode
is set to NSSegmentSwitchTracking.Momentary
, clicking a disabled segment in the toolbar results in a permanent disabled-looking selection:
I tried a ton of different things, including, but not limited to:
- when the selection changes, deselect the segment again
- when the toolbar validates, set
selectedSegment = -1
(“no selection”)
The problem isn’t with the NSSegmentedControl
, though. It’s with the NSToolbarItem
that corresponds to the disabled segments!
So during NSToolbarItemGroup.validate()
in my custom subclass I disable the corresponding subitems, too.
Some Example Code
This is the group:
class ToolbarItemGroup: NSToolbarItemGroup {
convenience init(itemIdentifier: String, validator: ActionItemValidation) {
self.init(itemIdentifier: itemIdentifier)
self.validator = validator
}
var validator: ActionItemValidation!
override func validate() {
validateSubitems()
validateSegmentedControl()
}
private func validateSubitems() {
self.subitems.forEach(validator.validate)
}
private func validateSegmentedControl() {
guard let segmentedControl = self.view as? AddDimensionSegmentedControl
else { return }
validator.validate(segmentedControl: segmentedControl)
}
}
The ActionItemValidation
type exposes two relevant methods:
validate(segmentedControl:)
validate(toolbarItem:)
The validate(toolbarItem:)
variant existed already to enable/disable buttons in the toolbar. I achieve this by tagging the items, for example:
0
equals “always on”,1
equals “enable only for selections”.
Re-using the method here was easy. I only had to set the tag for the group’s affected subitems.