From 5c28bb8e21531936a4c6cc3b244b671194e7c95b Mon Sep 17 00:00:00 2001 From: Scott Goodson Date: Tue, 8 Mar 2016 00:52:14 -0800 Subject: [PATCH] [ASScrollDirection] Ensure definitions of "positive" scroll direction in batch context match the layout controller. --- .../ASCollectionViewLayoutController.mm | 2 ++ .../Details/ASFlowLayoutController.mm | 35 +++++++++++-------- .../Details/CGRect+ASConvenience.h | 12 +++++++ .../Details/CGRect+ASConvenience.m | 6 ---- AsyncDisplayKit/Private/ASBatchFetching.m | 9 +++-- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm b/AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm index 0d5f69bdf5..62523a40be 100644 --- a/AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm +++ b/AsyncDisplayKit/Details/ASCollectionViewLayoutController.mm @@ -60,11 +60,13 @@ typedef struct ASRangeGeometry ASRangeGeometry; { NSArray *layoutAttributes = [_collectionViewLayout layoutAttributesForElementsInRect:rangeBounds]; NSMutableSet *indexPathSet = [NSMutableSet setWithCapacity:layoutAttributes.count]; + for (UICollectionViewLayoutAttributes *la in layoutAttributes) { //ASDisplayNodeAssert(![indexPathSet containsObject:la.indexPath], @"Shouldn't already contain indexPath"); ASDisplayNodeAssert(la.representedElementCategory != UICollectionElementCategoryDecorationView, @"UICollectionView decoration views are not supported by ASCollectionView"); [indexPathSet addObject:la.indexPath]; } + return indexPathSet; } diff --git a/AsyncDisplayKit/Details/ASFlowLayoutController.mm b/AsyncDisplayKit/Details/ASFlowLayoutController.mm index dce8065e8e..500bc1ae51 100644 --- a/AsyncDisplayKit/Details/ASFlowLayoutController.mm +++ b/AsyncDisplayKit/Details/ASFlowLayoutController.mm @@ -10,6 +10,7 @@ #import "ASAssert.h" #import "ASDisplayNode.h" #import "ASIndexPath.h" +#import "CGRect+ASConvenience.h" #include #include @@ -48,29 +49,33 @@ - (NSSet *)indexPathsForScrolling:(ASScrollDirection)scrollDirection rangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType { - CGFloat viewportScreenMetric; - ASScrollDirection leadingDirection; CGSize viewportSize = [self viewportSize]; + CGFloat viewportDirectionalSize = 0.0; + ASDirectionalScreenfulBuffer directionalBuffer = { 0, 0 }; + ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeMode:rangeMode rangeType:rangeType]; + if (_layoutDirection == ASFlowLayoutDirectionHorizontal) { - ASDisplayNodeAssert(scrollDirection == ASScrollDirectionNone || scrollDirection == ASScrollDirectionLeft || scrollDirection == ASScrollDirectionRight, @"Invalid scroll direction"); + ASDisplayNodeAssert(scrollDirection == ASScrollDirectionNone || + scrollDirection == ASScrollDirectionLeft || + scrollDirection == ASScrollDirectionRight, @"Invalid scroll direction"); - viewportScreenMetric = viewportSize.width; - leadingDirection = ASScrollDirectionLeft; + viewportDirectionalSize = viewportSize.width; + directionalBuffer = ASDirectionalScreenfulBufferHorizontal(scrollDirection, tuningParameters); } else { - ASDisplayNodeAssert(scrollDirection == ASScrollDirectionNone || scrollDirection == ASScrollDirectionUp || scrollDirection == ASScrollDirectionDown, @"Invalid scroll direction"); + ASDisplayNodeAssert(scrollDirection == ASScrollDirectionNone || + scrollDirection == ASScrollDirectionUp || + scrollDirection == ASScrollDirectionDown, @"Invalid scroll direction"); - viewportScreenMetric = viewportSize.height; - leadingDirection = ASScrollDirectionUp; + viewportDirectionalSize = viewportSize.height; + directionalBuffer = ASDirectionalScreenfulBufferVertical(scrollDirection, tuningParameters); } - - ASRangeTuningParameters tuningParameters = [self tuningParametersForRangeMode:rangeMode rangeType:rangeType]; - CGFloat backScreens = scrollDirection == leadingDirection ? tuningParameters.leadingBufferScreenfuls : tuningParameters.trailingBufferScreenfuls; - CGFloat frontScreens = scrollDirection == leadingDirection ? tuningParameters.trailingBufferScreenfuls : tuningParameters.leadingBufferScreenfuls; - - ASIndexPath startPath = [self findIndexPathAtDistance:(-backScreens * viewportScreenMetric) fromIndexPath:_visibleRange.start]; - ASIndexPath endPath = [self findIndexPathAtDistance:(frontScreens * viewportScreenMetric) fromIndexPath:_visibleRange.end]; + ASIndexPath startPath = [self findIndexPathAtDistance:(-directionalBuffer.negativeDirection * viewportDirectionalSize) + fromIndexPath:_visibleRange.start]; + + ASIndexPath endPath = [self findIndexPathAtDistance:(directionalBuffer.positiveDirection * viewportDirectionalSize) + fromIndexPath:_visibleRange.end]; ASDisplayNodeAssert(startPath.section <= endPath.section, @"startPath should never begin at a further position than endPath"); diff --git a/AsyncDisplayKit/Details/CGRect+ASConvenience.h b/AsyncDisplayKit/Details/CGRect+ASConvenience.h index 1d672b5f15..26ca6fd431 100644 --- a/AsyncDisplayKit/Details/CGRect+ASConvenience.h +++ b/AsyncDisplayKit/Details/CGRect+ASConvenience.h @@ -16,6 +16,18 @@ NS_ASSUME_NONNULL_BEGIN ASDISPLAYNODE_EXTERN_C_BEGIN +struct ASDirectionalScreenfulBuffer { + CGFloat positiveDirection; // Positive relative to iOS Core Animation layer coordinate space. + CGFloat negativeDirection; +}; +typedef struct ASDirectionalScreenfulBuffer ASDirectionalScreenfulBuffer; + +ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection, + ASRangeTuningParameters rangeTuningParameters); + +ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferVertical(ASScrollDirection scrollDirection, + ASRangeTuningParameters rangeTuningParameters); + CGRect CGRectExpandToRangeWithScrollableDirections(CGRect rect, ASRangeTuningParameters tuningParameters, ASScrollDirection scrollableDirections, diff --git a/AsyncDisplayKit/Details/CGRect+ASConvenience.m b/AsyncDisplayKit/Details/CGRect+ASConvenience.m index 312bac61f2..d3be682c78 100644 --- a/AsyncDisplayKit/Details/CGRect+ASConvenience.m +++ b/AsyncDisplayKit/Details/CGRect+ASConvenience.m @@ -10,12 +10,6 @@ #import "ASScrollDirection.h" #import "ASLayoutController.h" -struct ASDirectionalScreenfulBuffer { - CGFloat positiveDirection; // Positive relative to iOS Core Animation layer coordinate space. - CGFloat negativeDirection; -}; -typedef struct ASDirectionalScreenfulBuffer ASDirectionalScreenfulBuffer; - ASDirectionalScreenfulBuffer ASDirectionalScreenfulBufferHorizontal(ASScrollDirection scrollDirection, ASRangeTuningParameters rangeTuningParameters) { diff --git a/AsyncDisplayKit/Private/ASBatchFetching.m b/AsyncDisplayKit/Private/ASBatchFetching.m index c4027a70c5..b2a471e2da 100644 --- a/AsyncDisplayKit/Private/ASBatchFetching.m +++ b/AsyncDisplayKit/Private/ASBatchFetching.m @@ -19,20 +19,19 @@ BOOL ASDisplayShouldFetchBatchForContext(ASBatchContext *context, return NO; } - // only Up and Left scrolls are currently supported (tail loading) - if (scrollDirection != ASScrollDirectionUp && scrollDirection != ASScrollDirectionLeft) { + // only Down and Right scrolls are currently supported (tail loading) + if (scrollDirection != ASScrollDirectionDown && scrollDirection != ASScrollDirectionRight) { return NO; } // no fetching for null states - if (leadingScreens <= 0.0 || - CGRectEqualToRect(bounds, CGRectZero)) { + if (leadingScreens <= 0.0 || CGRectEqualToRect(bounds, CGRectZero)) { return NO; } CGFloat viewLength, offset, contentLength; - if (scrollDirection == ASScrollDirectionUp) { + if (scrollDirection == ASScrollDirectionDown) { viewLength = bounds.size.height; offset = targetOffset.y; contentLength = contentSize.height;