简体   繁体   中英

NSCollectionView dataSource not working properly

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.

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!

I had almost the same problem, and here is how I solved it.

First of all the problem I had :

  • when my collection view delegate was NOT implementing the NSCollectionViewDelegateFlowLayout protocol, everything was fine and the collectionView:itemForRepresentedObjectAtIndexPath method was called
  • when my collection view delegate was implementing the NSCollectionViewDelegateFlowLayout protocol, collectionView:itemForRepresentedObjectAtIndexPath method was NOT called

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 ?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM