Question

I have a view that gets used in each of my CollectionView's items. I have an IBOutlet to the CollectionViewItem from my view and I have that hooked up in Interface Builder. I want to access a value from the representedObject (which is a Core Data object) in my view code. Here is an example of what I'm trying to do -- access a sequence value of the representedObject:

In the .h file:

IBOutlet NSCollectionViewItem *item; // Connected in IB

In the .m file

NSString *seq = [[item representedObject] valueForKey:@"seq"];
NSLog(@"Seq: %@", seq); // returns Seq: (null)

I know that the seq is populated because I have it binded to a label in the CollectionViewItem view in IB using the representedObject.seq key path and that works.

Any idea why when I try to access the value for seq in the code for the view it returns null?

Was it helpful?

Solution

It's very likely that NSCollectionViewItem doesn't copy over IBOutlet connections from them item's views to the prototype NSCollectionViewItem. Hence, item is nil, so seq will also be nil.

The typical pattern for accessing the NSCollectionViewItem instance is to bind to the prototype. You mention that you did this and that it works. That is simply because that's the typical, supported way of doing it.

If you really need a connection directly to the item in a way that bindings cannot provide, you'll probably have to set it up manually. One way to do this is override NSCollectionViewItem's -copyWithZone:, call super, then make the connection manually.

OTHER TIPS

1) Subclass the NSView that is used for rendering an item in the collection view

2) In this subclass, add a delegate property

3) Sublcass the NSCollectionViewItem

4) Override the setView: method. Add a line to set the delegate property of the view to the NSCollectionViewItem instance (i.e. self).

Now, within NSView subclass, you will have access to the corresponding NSCollectionView item via the delegate property (e.g. you can access its representedObject).

I had the same problem, but found a very easy solution: I put the view in a different .xib and linked this in the NSCollectionViewItem (which is actually a NSViewController). Then the .xib will be deserialized for each cell and all outlets are set.

  1. Subclass NSView.
  2. Add delegate method to said subclass... something like - (void)mouseDownOnItemAtIndex:(NSUInteger)index to tell the listener that the user clicked on an item at a specific index.
  3. Pull the collection view by using self.superview in the same class. Create a variable to store an NSUInteger. Store the index of the item by using the method [[collectionView subviews] indexOfObject:self]. Pass that index in the delegate method index parameter.
  4. The class that conforms to the protocol defined in your NSView will now be able to hear from any mousedown events at a specific cell. If you want the representedObject of a specific item, just call collectionView:itemAtIndex and get the item by accessing it via the representedObject property on NSCollectionViewItem.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top