Double Click and NSCollectionView

Posted on 24 December 2009 by Johannes Fahrenkrug. Tags: Programming Tutorials Cocoa
I needed to capture double clicks on NSCollectionViewItems in an app I'm working on. This is unfortunately not something that's supported out-of-the-box. I found this post on CocoaDev helpful. However, since quite a few people will run into this issue, I want to explain step by step how to get this working with as little code as possible. We basically just need one custom NSView subclass and a NSCollectionViewItem subclass and a few connections in IB.
As a basis, we'll use Apple's demo app IconCollection. Download it and open it in XCode.

  1. Open MyViewController.h and add a delegate outlet to the IconViewBox. This will be necessary so we can pass the double click event on to NSCollectionViewItem and from there to the controller. It should look like this:

  2. Open MyViewController.m and alter the hitTest method to allow clicks and add a method to capture the double click to IconViewBox's implementation:

  3. Build and run. When you double click on items, you should see a log message in the console.
  4. Open IconViewPrototype.xib in IB and connect the View's delegate outlet with "File's Owner":

  5. Save IconViewPrototype.xib.
  6. Add a new file called IconCollectionItem (both the .h and the .m).
  7. IconCollectionItem.h:

  8. IconCollectionItem.m:

  9. Open IconViewPrototype.xib again and change the File Owner's class to "IconCollectionItem". Save.
  10. Open Collection.xib and also change the Collection View Item's class to "IconCollectionItem". Save.
  11. Build and run. When you double click now, you should see two log messages in the console.
  12. Finally, we want to be notified of the double click in our controller. So open up MyViewController.h and add a doubleClick method to the @interface:

  13. Open MyViewController.m and add the method implementation:

  14. Build and run: When you double click, the event gets passed on all the way to the controller and you'll see a log message on the console telling you which icon you have double clicked on. That's pretty nifty.
  15. Fin.
So to recap: Build an NSView subclass to capture the double click on an item (already existed in the IconCollection app in the form of the IconViewBox class), that NSView subclass needs a delegate outlet that we connect to the custom NSCollectionViewItem subclass (File's Owner in most cases) and finally the NSCollectionView's delegate outlet has to be connected to your view controller (already existed in the IconCollection app as well). 

If you've come up with a simpler or more elegant way to solve this, please let me know! 


Johannes Fahrenkrug said...

Beautiful! Thank you so much!

- Johannes

March 15, 2010 07:28 AM

Anonymous said...

Much easier if you just override the mouseDown method of your custom item view and use the sendAction method of NSApplication with nil as target.

NSApplication will find your doubleClick method in your controller automatically since the controller is in the responder chain

-(void)mouseDown:(NSEvent *)theEvent
[super mouseDown:theEvent];
if([theEvent clickCount] > 1)
[NSApp sendAction:@selector(collectionItemViewDoubleClick:) to:nil from:[self object]];

March 14, 2010 05:14 PM


Please keep it clean, everybody. Comments with profanity will be deleted.

blog comments powered by Disqus