I am learning about NSCollectionView compositional layout on macOS (12.4, Xcode 13.4). In the Swift version of this app everything works as expected, yet when converting it to Objective-C, while I get everything to compile, the app loads as blank.
I checked the outlets in the nib file (dataSource and delegate from Collection View to File's Owner), checked the creation of a reusable item (I build it through a custom nib). The error I get in the console when the app launches is as follows:
2022-07-21 15:26:25.817911+0200 Cocoa Pr L68 ObjC[14203:1414415] *** Assertion failure in -[_NSCollectionViewCore _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:], UICollectionView.m:6488
2022-07-21 15:26:25.818378+0200 Cocoa Pr L68 ObjC[14203:1414415] could not dequeue an item of kind: NSCollectionElementKindItem with identifier _NS:8 - must register a nib or a class for the identifier, or name a nib or class to match the identifier
Browsing the docs, I learned that NSCollectionView doesn't have a dequeueReusable kind of method like Table Views in iOS have so the first error is not clear to me. The second is even stranger because I've actually register a class for the identifier:
#import "CollectionViewController.h"
#import "CollectionViewItem.h"
@interface CollectionViewController ()
@property (weak) IBOutlet NSCollectionView *collectionView;
@end
@implementation CollectionViewController
@synthesize collectionView;
- (void)viewDidLoad {
[super viewDidLoad];
CollectionViewItem *collectionViewItem = [[CollectionViewItem alloc] init];
[collectionView registerClass:[NSCollectionViewItem class] forItemWithIdentifier:collectionViewItem.identifier];
[collectionView setCollectionViewLayout:self.listLayout];
}
The listLayout method is defined afterwards in the same file. All NSCollectionViewDataSource methods are properly defined as in the Swift version, for reference:
- (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView {
return 3;
}
- (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 20;
}
- (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {
NSCollectionViewItem *item = [collectionView makeItemWithIdentifier:collectionView.identifier forIndexPath:indexPath];
[item.textField setStringValue:[NSString stringWithFormat:@"%ld, %ld", indexPath.section, indexPath.item]];
return item;
}
The NSCollectionViewItem class is thus defined:
#import "CollectionViewItem.h"
@implementation CollectionViewItem
- (instancetype)init
{
self = [super init];
if (self) {
self.identifier = @"CollectionViewItemReuseIdentifier";
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
@end
I wonder what piece of the puzzle is missing as these errors, while apparently clear, seem to point to something that I have implemented. Have I implemented it wrong? Or not completely?
I would be very grateful to anyone shedding some light on all this.
Thank you
The registered class should be
CollectionViewIteminstead ofNSCollectionViewItem. Changeto
It's in the error
could not load the nibName: NSCollectionViewItem, but I'm so used toNSthat I didn't notice.