AsyncDisplayKit

UICollectionViewCell Interoperability

AsyncDisplayKit’s ASCollectionNode offers compatibility with synchronous, standard UICollectionViewCell objects alongside native ASCellNodes.

Note that these UIKit cells will not have the performance benefits of ASCellNodes (like preloading, async layout, and async drawing), even when mixed within the same ASCollectionNode.

However, this interoperability allows developers the flexibility to test out the framework without needing to convert all of their cells at once.

Implementing Interoperability

In order to use this feature, you must:

  1. Conform to ASCollectionDataSourceInterop and, optionally, ASCollectionDelegateInterop.
  2. Call registerCellClass: on the collectionNode.view (in viewDidLoad, or register an onDidLoad: block).
  3. Return nil from the nodeBlockForItem...: or nodeForItem...: method. Note: it is an error to return nil from within a nodeBlock, if you have returned a nodeBlock object.
  4. Lastly, you must implement a method to provide the size for the cell. There are two ways this is done:
    1. UICollectionViewFlowLayout (incl. ASPagerNode). Implement collectionNode:constrainedSizeForItemAtIndexPath:.
    2. Custom collection layouts. Set .view.layoutInspector and have it implement collectionView:constrainedSizeForNodeAtIndexPath:.

By default, the interop data source will only be consulted in cases where no ASCellNode is provided to AsyncDisplayKit. However, if .dequeuesCellsForNodeBackedItems is enabled, then the interop data source will always be consulted to dequeue cells, and will be expected to return _ASCollectionViewCells in cases where a node was provided.

CustomCollectionView Example App

The CustomCollectionView example project demonstrates how to use raw UIKit cells alongside native ASCellNodes.

Open the app and verify that kShowUICollectionViewCells is enabled in Sample/ViewController.m.

For this example, the data source method collectionNode:nodeBlockForItemAtIndexPath: is setup to return nil for every third cell. When nil is returned, ASCollectionNode will automatically query the cellForItemAtIndexPath: data source method.

Swift Objective-C
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode 
      nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
{
  if (kShowUICollectionViewCells && indexPath.item % 3 == 1) {
    // When enabled, return nil for every third cell and then 
    // cellForItemAtIndexPath: will be called.
    return nil;
  }
  
  UIImage *image = _sections[indexPath.section][indexPath.item];
  return ^{
    return [[ImageCellNode alloc] initWithImage:image];
  };
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView 
                  cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
  return [_collectionNode.view dequeueReusableCellWithReuseIdentifier:kReuseIdentifier 
                                                         forIndexPath:indexPath];
}
  

Run the app to see the orange UICollectionViewCells interspersed every 3rd cell among the ASCellNodes containing images.

Edit on GitHub