Reputation: 5154
I'd like to disable a NSButton when multiple items are selected in a NSTableView
which is connected to a NSArrayController
. I know I can easily disable a button when nothing is selected (binding to @count
), but I'm not sure how to reverse that so that @count
has to be == 1 to be enabled.
I am using Swift, but I'm more interested in the best method than a language specific implementation (unless the difference between Swift and Objective C is a big one in this instance).
How can I use Cocoa Bindings to disable a NSButton
if the selection includes more than one row?
Upvotes: 1
Views: 714
Reputation: 6918
Assuming your existing binding binds your button's enabled binding to your array controller's selectionIndexes property, you can achieve what you're after with a value transformer:
The button's state will be updated any time there's a change to the array controller's selectionIndexes property. Part of this update will involve a call to your value transformer, where the incoming value will be the updated selectionIndexes. Your transformer logic must transform this object into a boolean (enabled, or not-enabled), which will in turn determine the state of the button:
@objc(SelectionIndexesCountIsOneOrZeroTransformer)
public class SelectionIndexesCountIsOneOrZeroTransformer): NSValueTransformer {
override public class func allowsReverseTransformation() -> Bool {
return false
}
override public class func transformedValueClass() -> AnyClass {
return NSNumber.self
}
override public func transformedValue(value: AnyObject?) -> AnyObject? {
var retval = false
if let indexSet = value as? NSIndexSet {
retval = (indexSet.count < 2)
}
return retval
}
}
Upvotes: 2
Reputation: 285180
tableViewController
Declare a property selectionIndexes
in tableViewController
.
Objective-C:
@property NSIndexSet *selectionIndexes;
Swift:
dynamic var selectionIndexes = NSIndexSet()
Bind Selection Indexes
of the table view to that property.
In tableViewController
add these two methods
Objective-C:
+ (NSSet *)keyPathsForValuesAffectingEnableButton
{
return [NSSet setWithObject:@"selectionIndexes"];
}
- (BOOL)enableButton
{
return self.selectionIndexes.count < 2;
}
Swift:
override class func keyPathsForValuesAffectingEnableButton(key : String) -> Set<String> {
return Set<String>(["selectionIndexes"])
}
func enableButton() -> Bool
{
return selectionIndexes.count < 2
}
keyPathsForValuesAffecting<key>
is a method to easily implement a key-value observer.
Enabled
property of the button to enableButton
of tableViewController
.If you are using an array controller, bind Selection Indexes
of the table view to selectionIndexes
of the array controller and Selection Indexes
of the array controller to selectionIndexes
of tableViewController
.
Upvotes: 4