Skip navigation.
 
mlKeys dependent on NSArrayController's selection
FROM : Dave Dribin
DATE : Thu May 08 01:16:22 2008

Hi All,

I feel like I'm missing something basic here.  Say I have a table 
bound to an array controller.  And also say that each item in the 
array controller is a Person with firstName and lastName properties. 
Now say, I want to have a button that is only enabled when a Person 
with last name beginning with "D" is selected.  In my controller class:

@interface MyController : NSObject {
    IBOutlet NSArrayController * peopleController;
}

@property(readonly) BOOL canEnableButton;

@end

In Interface Builder I bind the button's "Enabled" to 
"MyController.canEnableButton".  The implementation for 
canEnableButton is this:

- (BOOL)canEnableButton {
    NSArray * selectedPeople = [peopleController selectedObjects];
    if ([selectedPeople count] < 1)
        return NO;

    Person * selectedPerson = [selectedPeople objectAtIndex:0];
    return [selectedPerson.lastName hasPrefix: @"D"];
}

Of course, canEnableButton is now dependent on the selection of 
NSArrayController.  Thus, I added this:

+ (NSSet *)keyPathsForValuesAffectingCanEnableButton {
    return [NSSet setWithObjects: 
@"peopleController.selectionIndexes", nil];
}

However, this does not trigger the button to update when the selection 
changes.  I've got two workarounds, neither of which I really like. 
I'm wondering if there's a better way.

Number 1
--------

In awakeFromNib:

    [peopleController addObserver:self
                        forKeyPath:@"selectionIndexes"
                          options:0
                          context:SelectionIndexesContext];


In observeValueForKeyPath:ofObject:change:context:

    if (context == SelectionIndexesContext)
    {
        [self willChangeValueForKey:@"canEnableButton"];
        [self didChangeValueForKey:@"canEnableButton"];
    }

This works, however, it just seems wrong to use {will/
did}ChangeValueForKey: like this.

Number 2
--------

Add this ivar to MyController:

    NSIndexSet * selectionIndexes;

Bind the array controller's "Selection Indexes" to "MyControler. 
selectionIndexes".  And add this to the implementation:

+ (NSSet *)keyPathsForValuesAffectingCanEnableButton {
    return [NSSet setWithObjects: @"selectionIndexes", nil];
}

Again, this works, but it seems silly to create an instance variable 
that I don't ever use.

Are there any other alternatives that I'm missing?

Thanks,

-Dave

Related mailsAuthorDate
mlKeys dependent on NSArrayController's selection Dave Dribin May 8, 01:16
mlRe: Keys dependent on NSArrayController's selection Sean McBride May 8, 01:58
mlRe: Keys dependent on NSArrayController's selection Dave Dribin May 8, 08:53
mlRe: Keys dependent on NSArrayController's selection Sean McBride May 8, 16:22
mlRe: Keys dependent on NSArrayController's selection Dave Dribin May 8, 20:45
mlRe: Keys dependent on NSArrayController's selection Sean McBride May 8, 21:02
mlRe: Keys dependent on NSArrayController's selection Hamish Allan Jun 17, 23:26