1
votes

I've been struggling with trying to create an NSCollectionView that has a set of NSCollectionViewItems with a custom view. The code works fine when the controls on the item view are standard AppKit controls, but once I add a custom NSView, there's no way to bind it from Interface Builder.

From spending some hours searching the internet, there appears to be a lot of options to solve this but all seem specialised. Is there some simple example code that demonstrates how, given a CustomImage * on the item view, to set the image property on that custom view?

The model that provides data for each item is:

@interface MyItem : NSObject
@property (retain, readwrite) NSImage * image;
@property (retain, readwrite) NSString * name;
@end

The NSCollectionViewItem subclass is:

@interface MyCollectionViewItem : NSCollectionViewItem

// Properties
@property (strong) IBOutlet NSTextField * name;
@property (strong) IBOutlet CustomImage * image;

@end

where CustomImage is simply a subclass of NSImageView.

I tried subclassing NSCollectionView and overriding newItemForRepresentedObject as some answers suggested and assigning there:

MyItem * item = (MyItem *)object;
MyCollectionViewItem * newItem = (MyCollectionViewItem *)[super newItemForRepresentedObject:object];

NSView *view = [newItem view];
[view bind:@"name" toObject:item withKeyPath:@"name" options:nil];
[view bind:@"image" toObject:item withKeyPath:@"image" options:nil];
return newItem;

but this just blew up in the bind call with an error that 'name' doesn't exist.

This should, in theory, be an extremely simple thing to solve but none of the answers I've found make this clear. An alternative would be to ditch NSCollectionView and use one of the simpler replacements on GitHub but I'd like to have a last attempt to see if this is solvable first.

Thanks!

1
Is is possible to bind directly to custom objects? I thought you had to do some boiler plate for that? tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings. Although this doesn't explain the problem with name blowing up.Daniel Farrell
There's a primitive degree of support for binding properties of custom objects. However, there's some confusion here about exactly what is being bound. Is CustomImage a view class or a model class? Neither of MyItem or MyCollectionViewItem is a view, but there's an attempt to bind name and image bindings of the view object, which would not have support for such bindings by default. Also, one image property is an NSImage while the other is a CustomImage but it's not clear how that's expected to be mapped. You need to show at least the interface for CustomImage.Ken Thomases
CustomImage is a subclass of NSImageView. I've clarified.Steven Palmer

1 Answers

1
votes

How did you add the CustomImage instance to the item view?

If you drag a "Custom View" in and then change the class, IB doesn't treat it like an NSImageView.

However, if you drag out an NSImageView and then change the class, IB should still treat it like an NSImageView and you should be able to bind its bindings like normal. In that case, you can bind its Value binding to the collection view item, model key path "representedObject.image".