So I’ve been neck deep in attempting to make my user interface pretty and simple to use. Anyone who thinks creating effective UIs is easy is either nuts or way smarter than me.
I’ve been going back and forth between using an NSTableView and an NSCollectionView for a list of items, and I think I’m settling on the NSCollectionView, but there are definitely some interesting challenges.
A couple of quick notes: I’m building for Snow Leopard so a few of my comments only apply to 10.6-only builds. Also, all my comments here come from my own experience with
NSCollectionView rather than actual knowledge about how it works internally. So, I could easily be wrong when I mention how I think something is working.
First up is
NSCollectionViewItem. In 10.6 it’s now a subclass of
NSViewController. Noticing this helped me understand a lot better how an
NSCollectionView might handled in code. Previously I never viewed it as something I should subclass, but now it seems obvious that if I want to handle actions from controls an item view, I put it in my own
There’s a problem when I take this a bit further though. The
NSCollectionViewItem that I set up in the nib isn’t actually the instance gets used when the application is running. That instance is just a prototype, underneath the hood it’ll be cloned, and Cocoa seems to take care of all the messy work of setting up the actions and bindings that I set up in Interface Builder.
It doesn’t, however, fix up my outlets automatically. Any outlets that I add to my subclass, I need to handle on my own. This can be done by overriding
copyWithZone:. There’s a catch however: this won’t work with outlets pointing to objects on the controller’s corresponding view.
NSCollectionViewItem cloned is paired with an
NSView (actually, from my understanding, only enough views will be created to fill the
NSCollectionView and they are reused). While the controllers are cloned with
copyWithZone: the views are not, they are simply created anew from the data in the nib for each additional one that’s needed. When you set up outlets pointing to items in that view, they’re pointing to items that, I believe, are never even actually used.
Unfortunately, I didn’t stumble upon a good way to have outlets pointing to objects in the view. The only way I could think of doing this was to set the
tag value on controls I’m interested in and search through subviews to find them. As I mentioned above, bindings seem to be handled by the framework as you’d expect, so hopefully outlets into the view won’t be needed.