Manage NSCollectionView and NSArrayController selection using observers
I was using NSCollectionView and NSArrayController and I need to catch the user selection of an item of the collection.
In the official documentation there isn’t a delegate method that gets called when the user selects an item from the collection view, so you must think about another way to trigger that event.
In my case, I thought about the selectionIndexes array or the selectedObjects / selectedObject of the array controller. It was a nice idea, but it didn’t work for me, because the bindings didn’t update in real time, and this happened when I tried to select an item with the mouse click button, but it didn’t happen if I used the arrow keys on the keyboard.
So the solution comes with observers (and Google
). You must attach an observer to the selectionIndexes array of the NSArrayController that you want to trigger.
In the collection view controller you’ll write:
//Observer for the collection view array controller selection: "selectionIndexes" - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if([keyPath isEqualTo:@"selectionIndexes"]) { //True if in the array controller of the collection view really exists at least a selected object if([[myArrayController selectedObjects] count] > 0) { NSLog(@"Selected objects: %@", [myArrayController selectedObjects]); } else { NSLog(@"Observer called but no objects where selected."); } } } -(void)awakeFromNib { //Add a new observer to the array controller of the collection view [myArrayController addObserver:self forKeyPath:@"selectionIndexes" options:NSKeyValueObservingOptionNew context:nil]; } - (void)dealloc { //Remove the collection view array controller selectionIndexes observer [myArrayController removeObserver:self forKeyPath:@"selectionIndexes"]; [super dealloc]; }
myArrayController is an instance of the NSArrayController defined in Interface Builder from which the collection view content array is binded to.

