diff --git a/AsyncDisplayKit/ASCollectionView.h b/AsyncDisplayKit/ASCollectionView.h index 418d22c2d3..b1ff87f251 100644 --- a/AsyncDisplayKit/ASCollectionView.h +++ b/AsyncDisplayKit/ASCollectionView.h @@ -90,6 +90,11 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, weak) id layoutInspector; +/** + * The ASInterfaceState of this collection view. + */ +@property (nonatomic, readonly) ASInterfaceState interfaceState; + /** * Perform a batch of updates asynchronously, optionally disabling all animations in the batch. This method must be called from the main thread. * The asyncDataSource must be updated to reflect the changes before the update block completes. diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 523d8f9f8f..d177b49173 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -17,7 +17,6 @@ #import "ASDisplayNode+FrameworkPrivate.h" #import "ASDisplayNode+Beta.h" #import "ASInternalHelpers.h" -#import "ASRangeController.h" #import "UICollectionViewLayout+ASConvenience.h" #import "_ASDisplayLayer.h" @@ -243,6 +242,19 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; return _flowLayoutInspector; } +- (ASInterfaceState)interfaceState +{ + ASCollectionNode *collectionNode = self.collectionNode; + if (collectionNode) { + return collectionNode.interfaceState; + } else { + // Until we can always create an associated ASCollectionNode without a retain cycle, + // we might be on our own to try to guess if we're visible. The node normally + // handles this even if it is the root / directly added to the view hierarchy. + return (self.window != nil ? ASInterfaceStateVisible : ASInterfaceStateNone); + } +} + #pragma mark - #pragma mark Overrides. @@ -535,16 +547,16 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; ASScrollDirection scrollableDirections = [self scrollableDirections]; if (ASScrollDirectionContainsHorizontalDirection(scrollableDirections)) { // Can scroll horizontally. - if (scrollVelocity.x >= 0) { + if (scrollVelocity.x > 0) { direction |= ASScrollDirectionRight; - } else { + } else if (scrollVelocity.x < 0) { direction |= ASScrollDirectionLeft; } } if (ASScrollDirectionContainsVerticalDirection(scrollableDirections)) { // Can scroll vertically. - if (scrollVelocity.y >= 0) { + if (scrollVelocity.y > 0) { direction |= ASScrollDirectionDown; - } else { + } else if (scrollVelocity.y < 0) { direction |= ASScrollDirectionUp; } } @@ -829,15 +841,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; - (ASInterfaceState)interfaceStateForRangeController:(ASRangeController *)rangeController { - ASCollectionNode *collectionNode = self.collectionNode; - if (collectionNode) { - return self.collectionNode.interfaceState; - } else { - // Until we can always create an associated ASCollectionNode without a retain cycle, - // we might be on our own to try to guess if we're visible. The node normally - // handles this even if it is the root / directly added to the view hierarchy. - return (self.window != nil ? ASInterfaceStateVisible : ASInterfaceStateNone); - } + return self.interfaceState; } - (NSArray *)rangeController:(ASRangeController *)rangeController nodesAtIndexPaths:(NSArray *)indexPaths diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index aa54b85671..63ba58d659 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -1585,6 +1585,7 @@ static BOOL ShouldUseNewRenderingRange = YES; { return ShouldUseNewRenderingRange; } + + (void)setShouldUseNewRenderingRange:(BOOL)shouldUseNewRenderingRange { ShouldUseNewRenderingRange = shouldUseNewRenderingRange; diff --git a/AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm b/AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm index c959e86434..f62e54f1cc 100644 --- a/AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm +++ b/AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm @@ -14,6 +14,7 @@ #import "ASCollectionView.h" #import "CGRect+ASConvenience.h" #import "UICollectionViewLayout+ASConvenience.h" +#import "ASDisplayNodeExtras.h" struct ASRangeGeometry { CGRect rangeBounds; @@ -164,4 +165,19 @@ typedef struct ASRangeGeometry ASRangeGeometry; return CGRectExpandToRangeWithScrollableDirections(rect, tuningParameters, _scrollableDirections, scrollDirection); } +- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType +{ + BOOL isVisible = ASInterfaceStateIncludesVisible(_collectionView.interfaceState); + BOOL isScrolling = (_collectionView.scrollDirection != ASScrollDirectionNone); + // When the collecion view is not visible or not scrolling, make display range only as big as visible range. + // This reduce early creation of views and layers. + if (!isVisible || !isScrolling) { + if (rangeType == ASLayoutRangeTypeDisplay) { + return [super tuningParametersForRangeType:ASLayoutRangeTypeVisible]; + } + } + + return [super tuningParametersForRangeType:rangeType]; +} + @end