Search code examples
objective-cmacoscocoacocoa-bindingsnsarraycontroller

Populate and bind an NSTableView to multiple array controllers


I have an API provided NSArray with a bunch of content objects – we'll call this acquiredFruit – and an empty NSMutableArray called likedFruit.

I've created NSArrayControllers for both arrays and bound my TableView to acquiredFruit.arrangedObjects. The first column of the tableView is bound to arrangedObjects.name and correctly shows all the delicious fruit.

I've created a second column with a checkbox – when the user fills the box I'd like to add the fruit to my likedFruit array. Unchecking the box should remove the fruit object from the likedFruit array.

Essentially I'd like my NSTableView to join between two array controllers. I have a feeling I should be making a single separate controller for this, but I'm unsure how to approach the problem.

I should also mention that I'm aware I could iterate through my array and construct another object with the fields I need, but my goal is to do this by using bindings, if possible.

Thoughts?


Solution

  • I think you should use one array controller.

    You can have an attribute on Fruit called liked. Now your "liked" checkbox column is connected to arrangedObjects.liked. Later, when you want to determine the set of all liked fruits, you can query your fruits array:

    NSArray * likedFruits = [ allFruitsArray filteredArrayUsingPredicate:[ NSPredicate predicateWithFormat:@"liked = YES"] ] ;
    

    If in another part of your UI you are displaying only liked fruit, you can set your array controller's filterPredicate to the predicate above to get just those fruits.

    EDIT: Let's say NSFruit is provided via someone else's API. Let's use the "General Technique for Adding Properties to Someone Else's Class":

    @interface NSFruit (Liking)
    @property ( nonatomic ) BOOL liked ;
    @end
    
    @implementation NSFruit (Liking)
    
    -(BOOL)liked
    {
        return [ objc_getAssociatedObject( self, "_abliked" ) boolValue ] ;
    }
    
    -(void)setLiked:(BOOL)b
    {
        objc_setAssociatedObject( self, "_abliked", [ NSNumber numberWithBool:b ], OBJC_ASSOCIATION_RETAIN_NONATOMIC ) ;
    }
    
    @end
    

    (I've written this same code for like 100 posts recently!)