Binding to an NSArrayController subclass
Binding to an NSArrayController subclass
- Subject: Binding to an NSArrayController subclass
- From: BJ Homer <email@hidden>
- Date: Fri, 15 May 2009 14:06:52 -0600
I have an NSTableView displaying a collection of rules. (Let's imagine
they're smart playlists, a la iTunes.) I set up an NSArrayController to
provide access to these playlists, and at that level, everything works. The
ArrayController has its contentSet as the set of playlists, and I can
display the name of each playlist by binding the Value of an NSTableColumn
to {bindTo = PlaylistArrayController, controllerKey = 'arrangedObjects',
modelKey = 'name'} in Interface Builder. (Forgive the odd notation, I'm
just trying to provide enough information.) With this configuration, the
tableview displays the name of each playlist correctly.
However, I also wanted to display the number of songs matching each
playlist. This is something the playlist won't know when it's created,
since files matching the rule might be added later. Hence, I can't bind
directly to a value on the Playlist object. Instead, I created a subclass
of NSArrayController called PlaylistArrayController, which has a reference
(connected through IBOutlets in interface builder) that can provide it
information about what files match the playlist. I changed the class of the
array controller in InterfaceBuilder, so that it's actually of class
PlaylistArrayController. Retrieving the name still works at this point.
I then attempted to add another key to the controller, parallel to
arrangedObjects. Where arrangedObjects returns an array of Playlists,
arrangedCounts should return an array of NSNumbers. This is the
implementation:
- (id)arrangedCounts {
NSArray *objects = [self arrangedObjects];
NSMutableArray *counts = [NSMutableArray arrayWithCapacity:[objects
count]];
Playlist *rule;
NSEnumerator *ruleEnumerator = [objects objectEnumerator];
while (rule = [ruleEnumerator nextObject]) {
int count = [playlistController countForRule:rule];
[counts addObject:[NSNumber numberWithInt:count]];
}
return counts;
}
However, when I attempt to bind another column to {bindTo =
PlaylistArrayController, controllerKey = 'arrangedCounts', modelKey =
blank}, I get problems. I have walked through the arrangedCounts method and
verified that it is, in fact, returning an array of NSNumbers just as I
expect. However, instead of displaying a number with each name, each row in
the table tries to display the entire array of counts. If I tweak
arrangedCounts to always return the string @"hi", then each row will display
"hi" in that column.
The only difference I can see between the two is that I am not using the
modelKey of the property, since I actually want to display the value of each
object (an NSNumber) itself. I've even tried adding an NSDictionary to my
counts array with the NSNumber as the value for the key "count", and setting
modelKey = 'count' on the bindings, but that still didn't work. Is there
some deep magic behind [NSArrayController arrangedObjects] that I don't have
access to? Is there a better way to solve my problem? I considered using
an NSValueTransformer, but I would have to create a static
playlistController object which would be shared app-wide, and I'd rather not
do that.
Please let me know if I'm missing some important piece of information here.
-BJ Homer
email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden