Reputation: 22856
I'm experimenting with the new NSCollectionView
API, introduced in El Capitan.
Following the WWDC video, I create a subclass of NSCollectionViewFlowLayout
to determine the layout of the collection view.
class Layout : NSCollectionViewFlowLayout {
override func prepareLayout() {
super.prepareLayout()
self.minimumInteritemSpacing = 0
self.minimumLineSpacing = 0
let cheight = self.collectionView!.bounds.height
let cwidth = self.collectionView!.bounds.width
self.itemSize = CGSizeMake(cwidth / 2.0, cheight / 6.0)
}
}
After that, I've created a NSObject
subclass to serve as data source.
class DataSource : NSObject, NSCollectionViewDataSource {
func collectionView(collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(collectionView: NSCollectionView, itemForRepresentedObjectAtIndexPath indexPath: NSIndexPath) -> NSCollectionViewItem {
/* DOESN'T GET CALLED! */
let item = collectionView.makeItemWithIdentifier("cell", forIndexPath: indexPath)
item.view.wantsLayer = true
item.view.layer?.backgroundColor = NSColor.redColor().CGColor
return item
}
}
The issue is that collectionView:itemForRepresentedObjectAtIndexPath:
never gets called.
This is how I initialise the collection view:
let collectionView = NSCollectionView(frame: view.bounds)
let dataSource = DataSource()
let layout = Layout()
collectionView.collectionViewLayout = layout
collectionView.registerClass(NSCollectionViewItem.self,
forItemWithIdentifier: "cell")
collectionView.dataSource = dataSource
collectionView.backgroundColors = [.blackColor()]
I can clearly see the collection view in its superview, but there are no cells.
Also, this line, if called outside the delegate (but after the cell class is registered) makes the app crash!
let item = collectionView.makeItemWithIdentifier("cell", forIndexPath: /*any index path*/)
Am I doing something wrong or is NSCollectionView
new API broken?
Thanks.
Upvotes: 8
Views: 3692
Reputation: 1759
The issue I was having was that I didn't register either nib or class for the items of the collection view. The symptoms were exactly like those you describe -- numberOfItemsInSection
was called, and itemForRepresentedObjectAtIndexPath
was not. After registering a nib, the method started being invoked. Here's the relevant answer -- https://stackoverflow.com/a/39516035/4635852
Upvotes: 0
Reputation: 2959
I had almost the same problem, and here is how I solved it.
First of all the problem I had :
I commented out every NSCollectionViewDelegateFlowLayout method in the delegate, and it turned out that if the method collectionView:layout:referenceSizeForHeaderInSection: was commented out, then everything was fine again (though I don't use headers).
It turned out that collectionView:layout:referenceSizeForHeaderInSection: was returning a NaN instead of 0.0 as the width in the size (stupid copy/paste mistake).
Are you sure you don't have the same kind of problem in what your layout is returning ?
Upvotes: 0
Reputation: 113
The method makeItemWithIdentifier is crucial and looks for .xib named "cell" in you bundle: you may need register it with registerNib:forItemWithIdentifier: if it comes from another bundle.
Thus your problem comes before that, since your collectionView:itemForRepresentedObjectAtIndexPath never gets called and this could arise from your pattern: why do you create a new class to serve as datasource and not use the same NSViewController where the NSCollectionView resides?
I always do so and with the new API all works perfectly. Hope this could help you!
Upvotes: 0