2828#import < AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h>
2929#import < AsyncDisplayKit/ASSectionContext.h>
3030#import < AsyncDisplayKit/ASCollectionView+Undeprecated.h>
31- #import < AsyncDisplayKit/ASCollectionInteropProtocols.h>
3231#import < AsyncDisplayKit/_ASHierarchyChangeSet.h>
3332
3433/* *
@@ -450,7 +449,7 @@ - (void)setAsyncDelegate:(id<ASCollectionDelegate>)asyncDelegate
450449 if (asyncDelegate == nil ) {
451450 _asyncDelegate = nil ;
452451 _proxyDelegate = _isDeallocating ? nil : [[ASCollectionViewProxy alloc ] initWithTarget: nil interceptor: self ];
453- _asyncDataSourceFlags = {};
452+ _asyncDelegateFlags = {};
454453 } else {
455454 _asyncDelegate = asyncDelegate;
456455 _proxyDelegate = [[ASCollectionViewProxy alloc ] initWithTarget: _asyncDelegate interceptor: self ];
@@ -857,49 +856,79 @@ - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollection
857856 return [[self nodeForItemAtIndexPath: indexPath] calculatedSize ];
858857}
859858
860- - (CGSize)collectionView : (UICollectionView *)collectionView layout : (UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection : (NSInteger )section
859+ - (CGSize)collectionView : (UICollectionView *)collectionView layout : (UICollectionViewLayout *)layout referenceSizeForHeaderInSection : (NSInteger )section
861860{
862- return [self supplementaryNodeForElementKind: UICollectionElementKindSectionHeader atIndexPath: [NSIndexPath indexPathForItem: 0 inSection: section]].calculatedSize ;
861+ ASCellNode *cell = [self supplementaryNodeForElementKind: UICollectionElementKindSectionHeader
862+ atIndexPath: [NSIndexPath indexPathForItem: 0 inSection: section]];
863+ if (cell.shouldUseUIKitCell && _asyncDelegateFlags.interop ) {
864+ if ([_asyncDelegate respondsToSelector: @selector (collectionView:layout:referenceSizeForHeaderInSection: )]) {
865+ return [(id )_asyncDelegate collectionView: collectionView layout: layout referenceSizeForHeaderInSection: section];
866+ }
867+ }
868+ return cell.calculatedSize ;
863869}
864870
865- - (CGSize)collectionView : (UICollectionView *)collectionView layout : (UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection : (NSInteger )section
871+ - (CGSize)collectionView : (UICollectionView *)collectionView layout : (UICollectionViewLayout *)layout referenceSizeForFooterInSection : (NSInteger )section
866872{
867- return [self supplementaryNodeForElementKind: UICollectionElementKindSectionFooter atIndexPath: [NSIndexPath indexPathForItem: 0 inSection: section]].calculatedSize ;
873+ ASCellNode *cell = [self supplementaryNodeForElementKind: UICollectionElementKindSectionFooter
874+ atIndexPath: [NSIndexPath indexPathForItem: 0 inSection: section]];
875+ if (cell.shouldUseUIKitCell && _asyncDelegateFlags.interop ) {
876+ if ([_asyncDelegate respondsToSelector: @selector (collectionView:layout:referenceSizeForFooterInSection: )]) {
877+ return [(id )_asyncDelegate collectionView: collectionView layout: layout referenceSizeForFooterInSection: section];
878+ }
879+ }
880+ return cell.calculatedSize ;
868881}
869882
870883- (UICollectionReusableView *)collectionView : (UICollectionView *)collectionView viewForSupplementaryElementOfKind : (NSString *)kind atIndexPath : (NSIndexPath *)indexPath
871884{
872- UICollectionReusableView *view;
873- if (_asyncDataSource && _asyncDataSourceFlags.interop ) {
885+ UICollectionReusableView *view = nil ;
886+ ASCellNode *node = [_dataController supplementaryNodeOfKind: kind atIndexPath: indexPath];
887+
888+ if (node.shouldUseUIKitCell && _asyncDataSourceFlags.interop ) {
874889 view = [(id <ASCollectionDataSourceInterop>)_asyncDataSource collectionView: collectionView viewForSupplementaryElementOfKind: kind atIndexPath: indexPath];
875890 } else {
891+ ASDisplayNodeAssert (node != nil , @" Supplementary node should exist. Kind = %@ , indexPath = %@ , collectionDataSource = %@ " , kind, indexPath, self);
892+ if ([_registeredSupplementaryKinds containsObject: kind] == NO ) {
893+ [self registerSupplementaryNodeOfKind: kind];
894+ }
876895 view = [self dequeueReusableSupplementaryViewOfKind: kind withReuseIdentifier: kReuseIdentifier forIndexPath: indexPath];
896+ if (node) {
897+ [_rangeController configureContentView: view forCellNode: node];
898+ }
877899 }
878-
879- ASCellNode *node = [_dataController supplementaryNodeOfKind: kind atIndexPath: indexPath];
880- ASDisplayNodeAssert (node != nil , @" Supplementary node should exist. Kind = %@ , indexPath = %@ , collectionDataSource = %@ " , kind, indexPath, self);
881- [_rangeController configureContentView: view forCellNode: node];
900+
882901 return view;
883902}
884903
885904- (UICollectionViewCell *)collectionView : (UICollectionView *)collectionView cellForItemAtIndexPath : (NSIndexPath *)indexPath
886905{
887- _ASCollectionViewCell *cell;
888- if (_asyncDataSource && _asyncDataSourceFlags.interop ) {
906+ UICollectionViewCell *cell = nil ;
907+ ASCellNode *node = [self nodeForItemAtIndexPath: indexPath];
908+
909+ if (node.shouldUseUIKitCell && _asyncDataSourceFlags.interop ) {
889910 cell = [(id <ASCollectionDataSourceInterop>)_asyncDataSource collectionView: collectionView cellForItemAtIndexPath: indexPath];
890911 } else {
912+ ASDisplayNodeAssert (node != nil , @" Cell node should exist. indexPath = %@ , collectionDataSource = %@ " , indexPath, self);
891913 cell = [self dequeueReusableCellWithReuseIdentifier: kReuseIdentifier forIndexPath: indexPath];
914+ [(_ASCollectionViewCell *)cell setNode: node];
915+ [_rangeController configureContentView: cell.contentView forCellNode: node];
892916 }
893-
894- ASCellNode *node = [self nodeForItemAtIndexPath: indexPath];
895- cell.node = node;
896- [_rangeController configureContentView: cell.contentView forCellNode: node];
897-
898917 return cell;
899918}
900919
901920- (void )collectionView : (UICollectionView *)collectionView willDisplayCell : (_ASCollectionViewCell *)cell forItemAtIndexPath : (NSIndexPath *)indexPath
902921{
922+ // Since _ASCollectionViewCell is not available for subclassing, this is faster than isKindOfClass:
923+ // We must exit early here, because only _ASCollectionViewCell implements the -node accessor method.
924+ if ([cell class ] != [_ASCollectionViewCell class ]) {
925+ if (_asyncDelegateFlags.interop ) {
926+ [(id <ASCollectionDelegateInterop>)_asyncDelegate collectionView: collectionView willDisplayCell: cell forItemAtIndexPath: indexPath];
927+ }
928+ [_rangeController setNeedsUpdate ];
929+ return ;
930+ }
931+
903932 ASCellNode *cellNode = [cell node ];
904933 cellNode.scrollView = collectionView;
905934
@@ -914,12 +943,8 @@ - (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(_ASCo
914943
915944 ASDisplayNodeAssertNotNil (cellNode, @" Expected node associated with cell that will be displayed not to be nil. indexPath: %@ " , indexPath);
916945
917- if (_asyncDelegateFlags.interop ) {
918- [(id <ASCollectionDelegateInterop>)_asyncDelegate collectionView: collectionView willDisplayCell: cell forItemAtIndexPath: indexPath];
919- } else if (_asyncDelegateFlags.collectionNodeWillDisplayItem ) {
920- if (ASCollectionNode *collectionNode = self.collectionNode ) {
921- [_asyncDelegate collectionNode: collectionNode willDisplayItemWithNode: cellNode];
922- }
946+ if (_asyncDelegateFlags.collectionNodeWillDisplayItem && self.collectionNode != nil ) {
947+ [_asyncDelegate collectionNode: self .collectionNode willDisplayItemWithNode: cellNode];
923948 } else if (_asyncDelegateFlags.collectionViewWillDisplayNodeForItem ) {
924949#pragma clang diagnostic push
925950#pragma clang diagnostic ignored "-Wdeprecated-declarations"
@@ -938,12 +963,20 @@ - (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(_ASCo
938963
939964- (void )collectionView : (UICollectionView *)collectionView didEndDisplayingCell : (_ASCollectionViewCell *)cell forItemAtIndexPath : (NSIndexPath *)indexPath
940965{
966+ // Since _ASCollectionViewCell is not available for subclassing, this is faster than isKindOfClass:
967+ // We must exit early here, because only _ASCollectionViewCell implements the -node accessor method.
968+ if ([cell class ] != [_ASCollectionViewCell class ]) {
969+ if (_asyncDelegateFlags.interop ) {
970+ [(id <ASCollectionDelegateInterop>)_asyncDelegate collectionView: collectionView didEndDisplayingCell: cell forItemAtIndexPath: indexPath];
971+ }
972+ [_rangeController setNeedsUpdate ];
973+ return ;
974+ }
975+
941976 ASCellNode *cellNode = [cell node ];
942977 ASDisplayNodeAssertNotNil (cellNode, @" Expected node associated with removed cell not to be nil." );
943978
944- if (_asyncDelegateFlags.interop ) {
945- [(id <ASCollectionDelegateInterop>)_asyncDelegate collectionView: collectionView didEndDisplayingCell: cell forItemAtIndexPath: indexPath];
946- } else if (_asyncDelegateFlags.collectionNodeDidEndDisplayingItem ) {
979+ if (_asyncDelegateFlags.collectionNodeDidEndDisplayingItem ) {
947980 if (ASCollectionNode *collectionNode = self.collectionNode ) {
948981 [_asyncDelegate collectionNode: collectionNode didEndDisplayingItemWithNode: cellNode];
949982 }
@@ -1369,46 +1402,49 @@ - (void)_beginBatchFetching
13691402
13701403#pragma mark - ASDataControllerSource
13711404
1372- - (ASCellNodeBlock)dataController : (ASDataController *)dataController nodeBlockAtIndexPath : (NSIndexPath *)indexPath {
1405+ - (ASCellNodeBlock)dataController : (ASDataController *)dataController nodeBlockAtIndexPath : (NSIndexPath *)indexPath
1406+ {
13731407 ASCellNodeBlock block = nil ;
1408+ ASCellNode *cell = nil ;
13741409
13751410 if (_asyncDataSourceFlags.collectionNodeNodeBlockForItem ) {
13761411 GET_COLLECTIONNODE_OR_RETURN (collectionNode, ^{ return [[ASCellNode alloc ] init ]; });
13771412 block = [_asyncDataSource collectionNode: collectionNode nodeBlockForItemAtIndexPath: indexPath];
13781413 } else if (_asyncDataSourceFlags.collectionNodeNodeForItem ) {
13791414 GET_COLLECTIONNODE_OR_RETURN (collectionNode, ^{ return [[ASCellNode alloc ] init ]; });
1380- ASCellNode *node = [_asyncDataSource collectionNode: collectionNode nodeForItemAtIndexPath: indexPath];
1381- if ([node isKindOfClass: [ASCellNode class ]]) {
1382- block = ^{
1383- return node;
1384- };
1385- } else {
1386- ASDisplayNodeFailAssert (@" Data source returned invalid node from tableNode:nodeForRowAtIndexPath:. Node: %@ " , node);
1387- }
1388- } else if (_asyncDataSourceFlags.collectionViewNodeBlockForItem ) {
1415+ cell = [_asyncDataSource collectionNode: collectionNode nodeForItemAtIndexPath: indexPath];
13891416#pragma clang diagnostic push
13901417#pragma clang diagnostic ignored "-Wdeprecated-declarations"
1418+ } else if (_asyncDataSourceFlags.collectionViewNodeBlockForItem ) {
13911419 block = [_asyncDataSource collectionView: self nodeBlockForItemAtIndexPath: indexPath];
13921420 } else if (_asyncDataSourceFlags.collectionViewNodeForItem ) {
1393- ASCellNode *node = [_asyncDataSource collectionView: self nodeForItemAtIndexPath: indexPath];
1421+ cell = [_asyncDataSource collectionView: self nodeForItemAtIndexPath: indexPath];
1422+ }
13941423#pragma clang diagnostic pop
1395- if ([node isKindOfClass: [ASCellNode class ]]) {
1424+
1425+ // Handle nil node block or cell
1426+ if (cell && [cell isKindOfClass: [ASCellNode class ]]) {
1427+ block = ^{
1428+ return cell;
1429+ };
1430+ }
1431+
1432+ if (block == nil ) {
1433+ if (_asyncDataSourceFlags.interop ) {
13961434 block = ^{
1397- return node;
1435+ ASCellNode *cell = [[ASCellNode alloc ] init ];
1436+ cell.shouldUseUIKitCell = YES ;
1437+ cell.style .preferredSize = CGSizeZero;
1438+ return cell;
13981439 };
13991440 } else {
1400- ASDisplayNodeFailAssert (@" Data source returned invalid node from tableView:nodeForRowAtIndexPath:. Node: %@ " , node);
1441+ ASDisplayNodeFailAssert (@" ASCollection could not get a node block for row at index path %@ : %@ , %@ . If you are trying to display a UICollectionViewCell, make sure your dataSource conforms to the <ASCollectionDataSourceInterop> protocol!" , indexPath, cell, block);
1442+ block = ^{
1443+ return [[ASCellNode alloc ] init ];
1444+ };
14011445 }
14021446 }
14031447
1404- // Handle nil node block
1405- if (block == nil ) {
1406- ASDisplayNodeFailAssert (@" ASTableNode could not get a node block for row at index path %@ " , indexPath);
1407- block = ^{
1408- return [[ASCellNode alloc ] init ];
1409- };
1410- }
1411-
14121448 // Wrap the node block
14131449 __weak __typeof__ (self) weakSelf = self;
14141450 return ^{
@@ -1419,7 +1455,7 @@ - (ASCellNodeBlock)dataController:(ASDataController *)dataController nodeBlockAt
14191455 node.interactionDelegate = strongSelf;
14201456 }
14211457 if (_inverted) {
1422- node.transform = CATransform3DMakeScale (1 , -1 , 1 ) ;
1458+ node.transform = CATransform3DMakeScale (1 , -1 , 1 ) ;
14231459 }
14241460 return node;
14251461 };
@@ -1479,6 +1515,12 @@ - (ASCellNode *)dataController:(ASCollectionDataController *)dataController supp
14791515 node = [_asyncDataSource collectionView: self nodeForSupplementaryElementOfKind: kind atIndexPath: indexPath];
14801516#pragma clang diagnostic pop
14811517 }
1518+
1519+ if (node == nil && _asyncDataSourceFlags.interop ) {
1520+ node = [[ASCellNode alloc ] init ];
1521+ node.shouldUseUIKitCell = YES ;
1522+ }
1523+
14821524 ASDisplayNodeAssert (node != nil , @" A node must be returned for supplementary element of kind '%@ ' at index path '%@ '" , kind, indexPath);
14831525 return node;
14841526}
0 commit comments