diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 33b7608fac..3257c2e3fc 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -427,6 +427,8 @@ E5B077FF1E69F4EB00C24B5B /* ASElementMap.h in Headers */ = {isa = PBXBuildFile; fileRef = E5B077FD1E69F4EB00C24B5B /* ASElementMap.h */; settings = {ATTRIBUTES = (Public, ); }; }; E5B078001E69F4EB00C24B5B /* ASElementMap.m in Sources */ = {isa = PBXBuildFile; fileRef = E5B077FE1E69F4EB00C24B5B /* ASElementMap.m */; }; E5B5B9D11E9BAD9800A6B726 /* ASCollectionLayoutContext+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = E5B5B9D01E9BAD9800A6B726 /* ASCollectionLayoutContext+Private.h */; }; + E5C347B11ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E5C347B01ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h */; }; + E5C347B31ECB40AA00EC4BE4 /* ASTableNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = E5C347B21ECB40AA00EC4BE4 /* ASTableNode+Beta.h */; }; E5E281741E71C833006B67C2 /* ASCollectionLayoutState.h in Headers */ = {isa = PBXBuildFile; fileRef = E5E281731E71C833006B67C2 /* ASCollectionLayoutState.h */; settings = {ATTRIBUTES = (Public, ); }; }; E5E281761E71C845006B67C2 /* ASCollectionLayoutState.m in Sources */ = {isa = PBXBuildFile; fileRef = E5E281751E71C845006B67C2 /* ASCollectionLayoutState.m */; }; F711994E1D20C21100568860 /* ASDisplayNodeExtrasTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F711994D1D20C21100568860 /* ASDisplayNodeExtrasTests.m */; }; @@ -883,6 +885,8 @@ E5B077FD1E69F4EB00C24B5B /* ASElementMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASElementMap.h; sourceTree = ""; }; E5B077FE1E69F4EB00C24B5B /* ASElementMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASElementMap.m; sourceTree = ""; }; E5B5B9D01E9BAD9800A6B726 /* ASCollectionLayoutContext+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASCollectionLayoutContext+Private.h"; sourceTree = ""; }; + E5C347B01ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBatchFetchingDelegate.h; sourceTree = ""; }; + E5C347B21ECB40AA00EC4BE4 /* ASTableNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASTableNode+Beta.h"; sourceTree = ""; }; E5E281731E71C833006B67C2 /* ASCollectionLayoutState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionLayoutState.h; sourceTree = ""; }; E5E281751E71C845006B67C2 /* ASCollectionLayoutState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionLayoutState.m; sourceTree = ""; }; EFA731F0396842FF8AB635EE /* libPods-AsyncDisplayKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AsyncDisplayKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1051,6 +1055,7 @@ 68FC85E11CE29B7E00EDD713 /* ASTabBarController.m */, B0F880581BEAEC7500D17647 /* ASTableNode.h */, 9CFFC6C11CCAC768006A6476 /* ASTableNode.mm */, + E5C347B21ECB40AA00EC4BE4 /* ASTableNode+Beta.h */, 055F1A3219ABD3E3004DAFF1 /* ASTableView.h */, 055F1A3319ABD3E3004DAFF1 /* ASTableView.mm */, AC7A2C161BDE11DF0093FE1A /* ASTableViewInternal.h */, @@ -1187,6 +1192,7 @@ 054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */, 299DA1A71A828D2900162D41 /* ASBatchContext.h */, 299DA1A81A828D2900162D41 /* ASBatchContext.mm */, + E5C347B01ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h */, 68C215561DE10D330019C4BC /* ASCollectionViewLayoutInspector.h */, 68C215571DE10D330019C4BC /* ASCollectionViewLayoutInspector.m */, 205F0E1B1B373A2C007741D0 /* ASCollectionViewLayoutController.h */, @@ -1687,6 +1693,7 @@ 68EE0DBE1C1B4ED300BA1B99 /* ASMainSerialQueue.h in Headers */, CCCCCCE11EC3EF060087FE10 /* ASTextUtilities.h in Headers */, B350624B1B010EFD0018CF92 /* _ASPendingState.h in Headers */, + E5C347B11ECB3D9200EC4BE4 /* ASBatchFetchingDelegate.h in Headers */, CC54A81C1D70079800296A24 /* ASDispatch.h in Headers */, B350624D1B010EFD0018CF92 /* _ASScopeTimer.h in Headers */, CC0F88631E4281E700576FED /* ASSupplementaryNodeSource.h in Headers */, @@ -1768,6 +1775,7 @@ 34EFC76E1B701CF400AD841F /* ASRatioLayoutSpec.h in Headers */, DB55C2671C641AE4004EDCF5 /* ASContextTransitioning.h in Headers */, CCA282C41E9EAE630037E8B7 /* ASLayerBackingTipProvider.h in Headers */, + E5C347B31ECB40AA00EC4BE4 /* ASTableNode+Beta.h in Headers */, 6900C5F41E8072DA00BCD75C /* ASImageNode+Private.h in Headers */, 68B0277B1C1A79D60041016B /* ASDisplayNode+Beta.h in Headers */, B350622D1B010EFD0018CF92 /* ASScrollDirection.h in Headers */, diff --git a/CHANGELOG.md b/CHANGELOG.md index d27a7fce51..ce58586f62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,3 +23,5 @@ - [ASCollectionNode] Fixed conversion of item index paths between node & view. [Adlai Holler](https://github.com/Adlai-Holler) [#262](https://github.com/TextureGroup/Texture/pull/262) - [Layout] Extract layout implementation code into it's own subcategories [Michael Schneider] (https://github.com/maicki)[#272](https://github.com/TextureGroup/Texture/pull/272) - [Fix] Fix a potential crash when cell nodes that need layout are deleted during the same runloop. [Adlai Holler](https://github.com/Adlai-Holler) [#279](https://github.com/TextureGroup/Texture/pull/279) +- [Batch fetching] Add ASBatchFetchingDelegate that takes scroll velocity and remaining time into account [Huy Nguyen](https://github.com/nguyenhuy) [#281](https://github.com/TextureGroup/Texture/pull/281) + diff --git a/Source/ASCollectionNode+Beta.h b/Source/ASCollectionNode+Beta.h index 9d0f17271e..b23f8d8b34 100644 --- a/Source/ASCollectionNode+Beta.h +++ b/Source/ASCollectionNode+Beta.h @@ -17,7 +17,7 @@ #import -@protocol ASCollectionViewLayoutFacilitatorProtocol, ASCollectionLayoutDelegate; +@protocol ASCollectionViewLayoutFacilitatorProtocol, ASCollectionLayoutDelegate, ASBatchFetchingDelegate; @class ASElementMap; NS_ASSUME_NONNULL_BEGIN @@ -38,6 +38,8 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, readonly, nullable) id layoutDelegate; +@property (nonatomic, weak) id batchFetchingDelegate; + - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id)layoutFacilitator; - (instancetype)initWithLayoutDelegate:(id)layoutDelegate layoutFacilitator:(nullable id)layoutFacilitator; diff --git a/Source/ASCollectionNode.mm b/Source/ASCollectionNode.mm index 9bcdc78061..128739888d 100644 --- a/Source/ASCollectionNode.mm +++ b/Source/ASCollectionNode.mm @@ -111,6 +111,7 @@ { ASDN::RecursiveMutex _environmentStateLock; Class _collectionViewClass; + id _batchFetchingDelegate; } @property (nonatomic) _ASCollectionPendingState *pendingState; @end @@ -442,6 +443,16 @@ return nil; } +- (void)setBatchFetchingDelegate:(id)batchFetchingDelegate +{ + _batchFetchingDelegate = batchFetchingDelegate; +} + +- (id)batchFetchingDelegate +{ + return _batchFetchingDelegate; +} + #pragma mark - Range Tuning - (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType diff --git a/Source/ASCollectionView.mm b/Source/ASCollectionView.mm index da796c3033..0fa91cb83d 100644 --- a/Source/ASCollectionView.mm +++ b/Source/ASCollectionView.mm @@ -22,6 +22,7 @@ #import #import #import +#import #import #import #import @@ -1347,7 +1348,7 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier"; if (targetContentOffset != NULL) { ASDisplayNodeAssert(_batchContext != nil, @"Batch context should exist"); - [self _beginBatchFetchingIfNeededWithContentOffset:*targetContentOffset]; + [self _beginBatchFetchingIfNeededWithContentOffset:*targetContentOffset velocity:velocity]; } if (_asyncDelegateFlags.scrollViewWillEndDragging) { @@ -1521,6 +1522,10 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier"; } } +- (id)batchFetchingDelegate{ + return self.collectionNode.batchFetchingDelegate; +} + - (void)_scheduleCheckForBatchFetchingForNumberOfChanges:(NSUInteger)changes { // Prevent fetching will continually trigger in a loop after reaching end of content and no new content was provided @@ -1542,12 +1547,12 @@ static NSString * const kReuseIdentifier = @"_ASCollectionReuseIdentifier"; return; } - [self _beginBatchFetchingIfNeededWithContentOffset:self.contentOffset]; + [self _beginBatchFetchingIfNeededWithContentOffset:self.contentOffset velocity:CGPointZero]; } -- (void)_beginBatchFetchingIfNeededWithContentOffset:(CGPoint)contentOffset +- (void)_beginBatchFetchingIfNeededWithContentOffset:(CGPoint)contentOffset velocity:(CGPoint)velocity { - if (ASDisplayShouldFetchBatchForScrollView(self, self.scrollDirection, self.scrollableDirections, contentOffset)) { + if (ASDisplayShouldFetchBatchForScrollView(self, self.scrollDirection, self.scrollableDirections, contentOffset, velocity)) { [self _beginBatchFetching]; } } diff --git a/Source/ASTableNode+Beta.h b/Source/ASTableNode+Beta.h new file mode 100644 index 0000000000..c2b27fa971 --- /dev/null +++ b/Source/ASTableNode+Beta.h @@ -0,0 +1,25 @@ +// +// ASTableNode+Beta.h +// Texture +// +// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// + +#import + +@protocol ASBatchFetchingDelegate; + +NS_ASSUME_NONNULL_BEGIN + +@interface ASTableNode (Beta) + +@property (nonatomic, weak) id batchFetchingDelegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Source/ASTableNode.mm b/Source/ASTableNode.mm index 9241e09559..3d0e8c57df 100644 --- a/Source/ASTableNode.mm +++ b/Source/ASTableNode.mm @@ -16,6 +16,8 @@ // #import +#import + #import #import #import @@ -68,6 +70,7 @@ @interface ASTableNode () { ASDN::RecursiveMutex _environmentStateLock; + id _batchFetchingDelegate; } @property (nonatomic, strong) _ASTablePendingState *pendingState; @@ -381,6 +384,16 @@ } } +- (void)setBatchFetchingDelegate:(id)batchFetchingDelegate +{ + _batchFetchingDelegate = batchFetchingDelegate; +} + +- (id)batchFetchingDelegate +{ + return _batchFetchingDelegate; +} + #pragma mark ASRangeControllerUpdateRangeProtocol - (void)updateCurrentRangeWithMode:(ASLayoutRangeMode)rangeMode diff --git a/Source/ASTableView.mm b/Source/ASTableView.mm index 31d1824419..08e6e266aa 100644 --- a/Source/ASTableView.mm +++ b/Source/ASTableView.mm @@ -30,7 +30,7 @@ #import #import #import -#import +#import #import #import #import @@ -1225,7 +1225,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; if (targetContentOffset != NULL) { ASDisplayNodeAssert(_batchContext != nil, @"Batch context should exist"); - [self _beginBatchFetchingIfNeededWithContentOffset:*targetContentOffset]; + [self _beginBatchFetchingIfNeededWithContentOffset:*targetContentOffset velocity:velocity]; } if (_asyncDelegateFlags.scrollViewWillEndDragging) { @@ -1381,6 +1381,11 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; } } +- (id)batchFetchingDelegate +{ + return self.tableNode.batchFetchingDelegate; +} + - (void)_scheduleCheckForBatchFetchingForNumberOfChanges:(NSUInteger)changes { // Prevent fetching will continually trigger in a loop after reaching end of content and no new content was provided @@ -1402,12 +1407,12 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell"; return; } - [self _beginBatchFetchingIfNeededWithContentOffset:self.contentOffset]; + [self _beginBatchFetchingIfNeededWithContentOffset:self.contentOffset velocity:CGPointZero]; } -- (void)_beginBatchFetchingIfNeededWithContentOffset:(CGPoint)contentOffset +- (void)_beginBatchFetchingIfNeededWithContentOffset:(CGPoint)contentOffset velocity:(CGPoint)velocity { - if (ASDisplayShouldFetchBatchForScrollView(self, self.scrollDirection, ASScrollDirectionVerticalDirections, contentOffset)) { + if (ASDisplayShouldFetchBatchForScrollView(self, self.scrollDirection, ASScrollDirectionVerticalDirections, contentOffset, velocity)) { [self _beginBatchFetching]; } } diff --git a/Source/Details/ASBatchFetchingDelegate.h b/Source/Details/ASBatchFetchingDelegate.h new file mode 100644 index 0000000000..972a03b182 --- /dev/null +++ b/Source/Details/ASBatchFetchingDelegate.h @@ -0,0 +1,27 @@ +// +// ASBatchFetchingDelegate.h +// Texture +// +// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// + +#import + +@protocol ASBatchFetchingDelegate + +/** + * @abstract Determine if batch fetching should begin based on the remaining time. + * If the delegate doesn't have enough information to confidently decide, it can take the given hint. + * + * @param remainingTime The amount of time left for user to reach the end of the scroll view's content. + * + * @param hint A hint for the delegate to fallback to. + */ +- (BOOL)shouldFetchBatchWithRemainingTime:(NSTimeInterval)remainingTime hint:(BOOL)hint; + +@end diff --git a/Source/Private/ASBatchFetching.h b/Source/Private/ASBatchFetching.h index 43d8769912..7ff4eb06db 100644 --- a/Source/Private/ASBatchFetching.h +++ b/Source/Private/ASBatchFetching.h @@ -21,13 +21,17 @@ ASDISPLAYNODE_EXTERN_C_BEGIN +NS_ASSUME_NONNULL_BEGIN + @class ASBatchContext; +@protocol ASBatchFetchingDelegate; @protocol ASBatchFetchingScrollView - (BOOL)canBatchFetch; - (ASBatchContext *)batchContext; - (CGFloat)leadingScreensForBatching; +- (nullable id)batchFetchingDelegate; @end @@ -39,9 +43,14 @@ ASDISPLAYNODE_EXTERN_C_BEGIN @param scrollDirection The current scrolling direction of the scroll view. @param scrollableDirections The possible scrolling directions of the scroll view. @param contentOffset The offset that the scrollview will scroll to. + @param velocity The velocity of the scroll view (in points) at the moment the touch was released. @return Whether or not the current state should proceed with batch fetching. */ -BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView *scrollView, ASScrollDirection scrollDirection, ASScrollDirection scrollableDirections, CGPoint contentOffset); +BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView *scrollView, + ASScrollDirection scrollDirection, + ASScrollDirection scrollableDirections, + CGPoint contentOffset, + CGPoint velocity); /** @@ -54,6 +63,8 @@ BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView delegate); +NS_ASSUME_NONNULL_END ASDISPLAYNODE_EXTERN_C_END diff --git a/Source/Private/ASBatchFetching.m b/Source/Private/ASBatchFetching.m index 000ba975ac..6c79b5ea48 100644 --- a/Source/Private/ASBatchFetching.m +++ b/Source/Private/ASBatchFetching.m @@ -17,8 +17,13 @@ #import #import +#import -BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView *scrollView, ASScrollDirection scrollDirection, ASScrollDirection scrollableDirections, CGPoint contentOffset) +BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView *scrollView, + ASScrollDirection scrollDirection, + ASScrollDirection scrollableDirections, + CGPoint contentOffset, + CGPoint velocity) { // Don't fetch if the scroll view does not allow if (![scrollView canBatchFetch]) { @@ -30,8 +35,9 @@ BOOL ASDisplayShouldFetchBatchForScrollView(UIScrollView delegate = scrollView.batchFetchingDelegate; BOOL visible = (scrollView.window != nil); - return ASDisplayShouldFetchBatchForContext(context, scrollDirection, scrollableDirections, bounds, contentSize, contentOffset, leadingScreens, visible); + return ASDisplayShouldFetchBatchForContext(context, scrollDirection, scrollableDirections, bounds, contentSize, contentOffset, leadingScreens, visible, velocity, delegate); } BOOL ASDisplayShouldFetchBatchForContext(ASBatchContext *context, @@ -41,7 +47,9 @@ BOOL ASDisplayShouldFetchBatchForContext(ASBatchContext *context, CGSize contentSize, CGPoint targetOffset, CGFloat leadingScreens, - BOOL visible) + BOOL visible, + CGPoint velocity, + id delegate) { // Do not allow fetching if a batch is already in-flight and hasn't been completed or cancelled if ([context isFetching]) { @@ -53,16 +61,18 @@ BOOL ASDisplayShouldFetchBatchForContext(ASBatchContext *context, return NO; } - CGFloat viewLength, offset, contentLength; + CGFloat viewLength, offset, contentLength, velocityLength; if (ASScrollDirectionContainsVerticalDirection(scrollableDirections)) { viewLength = bounds.size.height; offset = targetOffset.y; contentLength = contentSize.height; + velocityLength = velocity.y; } else { // horizontal / right viewLength = bounds.size.width; offset = targetOffset.x; contentLength = contentSize.width; + velocityLength = velocity.x; } BOOL hasSmallContent = contentLength < viewLength; @@ -84,6 +94,12 @@ BOOL ASDisplayShouldFetchBatchForContext(ASBatchContext *context, CGFloat triggerDistance = viewLength * leadingScreens; CGFloat remainingDistance = contentLength - viewLength - offset; - - return remainingDistance <= triggerDistance; + BOOL result = remainingDistance <= triggerDistance; + + if (delegate != nil && (velocityLength = round(fabs(velocityLength))) > 0) { + NSTimeInterval remainingTime = remainingDistance / (velocityLength * 1000); + result = [delegate shouldFetchBatchWithRemainingTime:remainingTime hint:result]; + } + + return result; } diff --git a/Tests/ASBatchFetchingTests.m b/Tests/ASBatchFetchingTests.m index 4cb08e142a..97eab3576c 100644 --- a/Tests/ASBatchFetchingTests.m +++ b/Tests/ASBatchFetchingTests.m @@ -38,26 +38,26 @@ - (void)testBatchNullState { ASBatchContext *context = [[ASBatchContext alloc] init]; - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, CGRectZero, CGSizeZero, CGPointZero, 0.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, CGRectZero, CGSizeZero, CGPointZero, 0.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == NO, @"Should not fetch in the null state"); } - (void)testBatchAlreadyFetching { ASBatchContext *context = [[ASBatchContext alloc] init]; [context beginBatchFetching]; - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == NO, @"Should not fetch when context is already fetching"); } - (void)testUnsupportedScrollDirections { ASBatchContext *context = [[ASBatchContext alloc] init]; - BOOL fetchRight = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionRight, ASScrollDirectionHorizontalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES); + BOOL fetchRight = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionRight, ASScrollDirectionHorizontalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES, CGPointZero, nil); XCTAssert(fetchRight == YES, @"Should fetch for scrolling right"); - BOOL fetchDown = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES); + BOOL fetchDown = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES, CGPointZero, nil); XCTAssert(fetchDown == YES, @"Should fetch for scrolling down"); - BOOL fetchUp = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionUp, ASScrollDirectionVerticalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES); + BOOL fetchUp = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionUp, ASScrollDirectionVerticalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES, CGPointZero, nil); XCTAssert(fetchUp == NO, @"Should not fetch for scrolling up"); - BOOL fetchLeft = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionLeft, ASScrollDirectionHorizontalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES); + BOOL fetchLeft = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionLeft, ASScrollDirectionHorizontalDirections, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0, YES, CGPointZero, nil); XCTAssert(fetchLeft == NO, @"Should not fetch for scrolling left"); } @@ -65,7 +65,7 @@ CGFloat screen = 1.0; ASBatchContext *context = [[ASBatchContext alloc] init]; // scroll to 1-screen top offset, height is 1 screen, so bottom is 1 screen away from end of content - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 1.0), 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 1.0), 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == YES, @"Fetch should begin when vertically scrolling to exactly 1 leading screen away"); } @@ -73,7 +73,7 @@ CGFloat screen = 1.0; ASBatchContext *context = [[ASBatchContext alloc] init]; // 3 screens of content, scroll only 1/2 of one screen - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 0.5), 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 0.5), 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == NO, @"Fetch should not begin when vertically scrolling less than the leading distance away"); } @@ -81,7 +81,7 @@ CGFloat screen = 1.0; ASBatchContext *context = [[ASBatchContext alloc] init]; // 3 screens of content, top offset to 3-screens, height 1 screen, so its 1 screen past the leading - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 3.0), 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 3.0), 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == YES, @"Fetch should begin when vertically scrolling past the content size"); } @@ -89,7 +89,7 @@ CGFloat screen = 1.0; ASBatchContext *context = [[ASBatchContext alloc] init]; // scroll to 1-screen left offset, width is 1 screen, so right is 1 screen away from end of content - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionRight, ASScrollDirectionVerticalDirections, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 1.0), 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionRight, ASScrollDirectionVerticalDirections, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 1.0), 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == YES, @"Fetch should begin when horizontally scrolling to exactly 1 leading screen away"); } @@ -97,7 +97,7 @@ CGFloat screen = 1.0; ASBatchContext *context = [[ASBatchContext alloc] init]; // 3 screens of content, scroll only 1/2 of one screen - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionLeft, ASScrollDirectionHorizontalDirections, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 0.5), 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionLeft, ASScrollDirectionHorizontalDirections, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 0.5), 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == NO, @"Fetch should not begin when horizontally scrolling less than the leading distance away"); } @@ -105,7 +105,7 @@ CGFloat screen = 1.0; ASBatchContext *context = [[ASBatchContext alloc] init]; // 3 screens of content, left offset to 3-screens, width 1 screen, so its 1 screen past the leading - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionHorizontalDirections, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 3.0), 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionHorizontalDirections, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 3.0), 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == YES, @"Fetch should begin when vertically scrolling past the content size"); } @@ -113,7 +113,7 @@ CGFloat screen = 1.0; ASBatchContext *context = [[ASBatchContext alloc] init]; // when the content size is < screen size, the target offset will always be 0 - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 0.5), VERTICAL_OFFSET(0.0), 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, ASScrollDirectionVerticalDirections, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 0.5), VERTICAL_OFFSET(0.0), 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == YES, @"Fetch should begin when the target is 0 and the content size is smaller than the scree"); } @@ -121,7 +121,7 @@ CGFloat screen = 1.0; ASBatchContext *context = [[ASBatchContext alloc] init]; // when the content size is < screen size, the target offset will always be 0 - BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionRight, ASScrollDirectionHorizontalDirections, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 0.5), HORIZONTAL_OFFSET(0.0), 1.0, YES); + BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionRight, ASScrollDirectionHorizontalDirections, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 0.5), HORIZONTAL_OFFSET(0.0), 1.0, YES, CGPointZero, nil); XCTAssert(shouldFetch == YES, @"Fetch should begin when the target is 0 and the content size is smaller than the scree"); }