views:

17

answers:

0

Basically in IB where there are the options "arrangedObjects", "selection" etc in the "Controller Key" drop down, is it possible to create my own entry in there to bind to?

If possible this would allow me to bind certain text boxes to filtered aspects of the array held by the ArrayController (and furthermore use operators like @count on the sub-array).

The problem, I've already outlined HERE.

My attempt so far at an implementation is as follows:

  1. Sub-Classed NSArrayController to create a property of the array controller, blueCarSubArray, and implemented KVC getter and setter.
  2. Registered OBArrayController to observe its own "arrangedObjects" and "color" keys.

The code is as follows:

//  OBArrayController.h
#import <Cocoa/Cocoa.h>

@interface OBArrayController : NSArrayController {
NSArray *blueCarSubArray;
}
-(NSArray *)blueCarSubArray;
-(void)setBlueCarSubArray;
@end  



//  OBArrayController.h
#import "OBArrayController.h"

@implementation OBArrayController 
-(void)awakeFromNib{  
[self addObserver:self forKeyPath:@"arrangedObjects" options:NSKeyValueObservingOptionNew context:NULL];  
[self addObserver:self forKeyPath:@"color" options:NSKeyValueObservingOptionNew context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqual:@"arrangedObjects"] | [keyPath isEqual:@"color"]) {
    [self setBlueCarSubArray];
}
[super observeValueForKeyPath:keyPath
                     ofObject:object
                       change:change
                      context:context];
}  

-(void)setBlueCarSubArray{
    NSPredicate *bluePredicate = [NSPredicate predicateWithFormat:@"color == %@", [NSString @"blue"]];  
blueCarSubArray = [[self arrangedObjects] filteredArrayUsingPredicate:bluePredicate];
}

-(NSArray *)blueCarSubArray{
    return blueCarSubArray;
}
@end

Using NSLog outputs to follow the program I see that the setter is called whenever an object is added or removed in the array (as the key "arrangedObjects" has had a change") and also whenever the color of an object is changed.

Also by making NSLog call the getter whenever the setter is called I can see that the array is being correctly filtered and the value of blueCarSubArray updated.

However Binding a text box in IB to: the ArrayController, Controller Key:"blueCarSubArray", Model Key Path "@count", doesn't work! The text box doesn't get updated.

Furthermore, using a button to try to execute:

NSLog(@"I'm ouputting %@", [theCarArrayController valueForKey:@"blueCarSubArray"] );

causes the program to crash.

Can anyone please shed some light.

Thanks, Oli

related questions