I am struggling with a design issue: I have an
NSCollectionView that contains several items (it's binded to an
NSArrayController which is, in turn, binded to a
NSManagedObjectContext). I have decided to draw the view for each single item programmatically, mainly because I noticed that nesting several
NSViews inside the Item View creates performance issues when there are more than a certain number of items in the collection view.
Consider the following hierarchy:
NSView. (The default one used by
NSCollectionView). My custom
NSView contains several layers, some are
CATextLayers, others are regular
CALayers, and they all animate together (within the same
CATransaction) whenever they need to. The issue here is that each
CALayer needs to display the content of some data which is accessible through the
representedObject property of the
NSCollectionViewItem... which owns the
NSView! I have two options (probably many more, I'm more than open to suggestions):
- I replicate the
representedObject from the
NSCollectionViewItem to its
NSView, and I keep it consistent througout the execution of the program. I don't really like this one.
- I expose the
CALayers in the
NSView, and I set their content/string from within the
setRepresentedObject: method. I like this one better, because there is no data saved in the
NSView (except for that which is being shown by through the layers, of course).
Am I wrong? Is there a more elegant solution?
Thanks in advance, I really apreciate the help. Cheers
Came across this question quite late, and I thought it was an interesting design problem.
In case you haven't cracked this one or didn't like either of your solutions:
I would suggest writing an NSCollectionViewItem subclass that observes the self.representedObject key path(s), and refreshes its view and subviews when the model object changes.
NSCollectionViewItem is an NSViewController, which implies it should be responsible for managing its views. You can respect that by having the view layer that it works with, as a user-facing representation of its model object, held in its representedObject property. So, by watching all the necessary properties of the model using KVO, you should have a neat place to invoke all the view operations concerning 'rendering' the model. You should have full control at this funnel on whether you would like to work with the NSView API or the CALayer API.
Based on how complicated your prototype item view is, the size and volatility of the item set, the 'liveliness' requirement of the UI, and other factors, you might be able to get away with a very coarse-grain observation of the model, or need a very fine-grained one - I hope you got used to working with the KVO API!
I'm keen to also hear what choice you made in the end.