From aece8365ddff6e75f802d690d4a4f8ccb354977d Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Thu, 6 Oct 2016 19:42:36 -0700 Subject: [PATCH] Adjust layoutAttributes logic to account for new iOS 10 behavior (#2354) --- AsyncDisplayKit/ASCollectionView.mm | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 94776223..8c79a019 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -73,10 +73,15 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; [_node __setHighlightedFromUIKit:highlighted]; } +- (void)setLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes +{ + _layoutAttributes = layoutAttributes; + _node.layoutAttributes = layoutAttributes; +} + - (void)prepareForReuse { - _layoutAttributes = nil; - _node.layoutAttributes = nil; + self.layoutAttributes = nil; // Need to clear node pointer before UIKit calls setSelected:NO / setHighlighted:NO on its cells self.node = nil; @@ -92,8 +97,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; */ - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { - _layoutAttributes = layoutAttributes; - _node.layoutAttributes = layoutAttributes; + self.layoutAttributes = layoutAttributes; } @end @@ -694,6 +698,15 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; ASCellNode *cellNode = [cell node]; cellNode.scrollView = collectionView; + // Under iOS 10+, cells may be removed/re-added to the collection view without + // receiving prepareForReuse/applyLayoutAttributes, as an optimization for e.g. + // if the user is scrolling back and forth across a small set of items. + // In this case, we have to fetch the layout attributes manually. + // This may be possible under iOS < 10 but it has not been observed yet. + if (cell.layoutAttributes == nil) { + cell.layoutAttributes = [collectionView layoutAttributesForItemAtIndexPath:indexPath]; + } + ASDisplayNodeAssertNotNil(cellNode, @"Expected node associated with cell that will be displayed not to be nil. indexPath: %@", indexPath); if (_asyncDelegateFlags.asyncDelegateCollectionViewWillDisplayNodeForItemAtIndexPath) { @@ -726,7 +739,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; [_cellsForVisibilityUpdates removeObject:cell]; cellNode.scrollView = nil; - cellNode.layoutAttributes = nil; + cell.layoutAttributes = nil; }