mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Unit tests for batch fetching
This commit is contained in:
@@ -145,6 +145,9 @@
|
|||||||
292C59A31A956527007E5DD6 /* ASRangeHandlerRender.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C599D1A956527007E5DD6 /* ASRangeHandlerRender.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
292C59A31A956527007E5DD6 /* ASRangeHandlerRender.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C599D1A956527007E5DD6 /* ASRangeHandlerRender.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
292C59A41A956527007E5DD6 /* ASRangeHandlerRender.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292C599E1A956527007E5DD6 /* ASRangeHandlerRender.mm */; };
|
292C59A41A956527007E5DD6 /* ASRangeHandlerRender.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292C599E1A956527007E5DD6 /* ASRangeHandlerRender.mm */; };
|
||||||
299DA1A91A828D2900162D41 /* ASBatchContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 299DA1A71A828D2900162D41 /* ASBatchContext.h */; };
|
299DA1A91A828D2900162D41 /* ASBatchContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 299DA1A71A828D2900162D41 /* ASBatchContext.h */; };
|
||||||
|
296A0A2E1A9516B2005ACEAA /* ASBatchFetching.h in Headers */ = {isa = PBXBuildFile; fileRef = 296A0A2C1A9516B2005ACEAA /* ASBatchFetching.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
296A0A2F1A9516B2005ACEAA /* ASBatchFetching.m in Sources */ = {isa = PBXBuildFile; fileRef = 296A0A2D1A9516B2005ACEAA /* ASBatchFetching.m */; };
|
||||||
|
296A0A351A951ABF005ACEAA /* ASBatchFetchingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.m */; };
|
||||||
299DA1A91A828D2900162D41 /* ASBatchContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 299DA1A71A828D2900162D41 /* ASBatchContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
299DA1A91A828D2900162D41 /* ASBatchContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 299DA1A71A828D2900162D41 /* ASBatchContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
299DA1AA1A828D2900162D41 /* ASBatchContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 299DA1A81A828D2900162D41 /* ASBatchContext.m */; };
|
299DA1AA1A828D2900162D41 /* ASBatchContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 299DA1A81A828D2900162D41 /* ASBatchContext.m */; };
|
||||||
3C9C128519E616EF00E942A0 /* ASTableViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C9C128419E616EF00E942A0 /* ASTableViewTests.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
3C9C128519E616EF00E942A0 /* ASTableViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C9C128419E616EF00E942A0 /* ASTableViewTests.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
|
||||||
@@ -299,6 +302,10 @@
|
|||||||
292C599C1A956527007E5DD6 /* ASRangeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeHandler.h; sourceTree = "<group>"; };
|
292C599C1A956527007E5DD6 /* ASRangeHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeHandler.h; sourceTree = "<group>"; };
|
||||||
292C599D1A956527007E5DD6 /* ASRangeHandlerRender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeHandlerRender.h; sourceTree = "<group>"; };
|
292C599D1A956527007E5DD6 /* ASRangeHandlerRender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeHandlerRender.h; sourceTree = "<group>"; };
|
||||||
292C599E1A956527007E5DD6 /* ASRangeHandlerRender.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeHandlerRender.mm; sourceTree = "<group>"; };
|
292C599E1A956527007E5DD6 /* ASRangeHandlerRender.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeHandlerRender.mm; sourceTree = "<group>"; };
|
||||||
|
296A0A2C1A9516B2005ACEAA /* ASBatchFetching.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBatchFetching.h; sourceTree = "<group>"; };
|
||||||
|
296A0A2D1A9516B2005ACEAA /* ASBatchFetching.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBatchFetching.m; sourceTree = "<group>"; };
|
||||||
|
296A0A311A951715005ACEAA /* ASScrollDirection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASScrollDirection.h; path = AsyncDisplayKit/Details/ASScrollDirection.h; sourceTree = SOURCE_ROOT; };
|
||||||
|
296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBatchFetchingTests.m; sourceTree = "<group>"; };
|
||||||
299DA1A71A828D2900162D41 /* ASBatchContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBatchContext.h; sourceTree = "<group>"; };
|
299DA1A71A828D2900162D41 /* ASBatchContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBatchContext.h; sourceTree = "<group>"; };
|
||||||
299DA1A81A828D2900162D41 /* ASBatchContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBatchContext.m; sourceTree = "<group>"; };
|
299DA1A81A828D2900162D41 /* ASBatchContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASBatchContext.m; sourceTree = "<group>"; };
|
||||||
3C9C128419E616EF00E942A0 /* ASTableViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewTests.m; sourceTree = "<group>"; };
|
3C9C128419E616EF00E942A0 /* ASTableViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASTableViewTests.m; sourceTree = "<group>"; };
|
||||||
@@ -432,6 +439,7 @@
|
|||||||
058D09C5195D04C000B7D73C /* AsyncDisplayKitTests */ = {
|
058D09C5195D04C000B7D73C /* AsyncDisplayKitTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
296A0A341A951ABF005ACEAA /* ASBatchFetchingTests.m */,
|
||||||
2911485B1A77147A005D0878 /* ASControlNodeTests.m */,
|
2911485B1A77147A005D0878 /* ASControlNodeTests.m */,
|
||||||
058D0A2D195D057000B7D73C /* ASDisplayLayerTests.m */,
|
058D0A2D195D057000B7D73C /* ASDisplayLayerTests.m */,
|
||||||
058D0A2E195D057000B7D73C /* ASDisplayNodeAppearanceTests.m */,
|
058D0A2E195D057000B7D73C /* ASDisplayNodeAppearanceTests.m */,
|
||||||
@@ -472,6 +480,8 @@
|
|||||||
054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */,
|
054963481A1EA066000F8E56 /* ASBasicImageDownloader.mm */,
|
||||||
299DA1A71A828D2900162D41 /* ASBatchContext.h */,
|
299DA1A71A828D2900162D41 /* ASBatchContext.h */,
|
||||||
299DA1A81A828D2900162D41 /* ASBatchContext.m */,
|
299DA1A81A828D2900162D41 /* ASBatchContext.m */,
|
||||||
|
296A0A2C1A9516B2005ACEAA /* ASBatchFetching.h */,
|
||||||
|
296A0A2D1A9516B2005ACEAA /* ASBatchFetching.m */,
|
||||||
464052191A3F83C40061C0BA /* ASDataController.h */,
|
464052191A3F83C40061C0BA /* ASDataController.h */,
|
||||||
4640521A1A3F83C40061C0BA /* ASDataController.mm */,
|
4640521A1A3F83C40061C0BA /* ASDataController.mm */,
|
||||||
05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */,
|
05A6D05819D0EB64002DD95E /* ASDealloc2MainObject.h */,
|
||||||
@@ -497,6 +507,7 @@
|
|||||||
292C599C1A956527007E5DD6 /* ASRangeHandler.h */,
|
292C599C1A956527007E5DD6 /* ASRangeHandler.h */,
|
||||||
292C599D1A956527007E5DD6 /* ASRangeHandlerRender.h */,
|
292C599D1A956527007E5DD6 /* ASRangeHandlerRender.h */,
|
||||||
292C599E1A956527007E5DD6 /* ASRangeHandlerRender.mm */,
|
292C599E1A956527007E5DD6 /* ASRangeHandlerRender.mm */,
|
||||||
|
296A0A311A951715005ACEAA /* ASScrollDirection.h */,
|
||||||
058D09EA195D050800B7D73C /* ASTextNodeCoreTextAdditions.h */,
|
058D09EA195D050800B7D73C /* ASTextNodeCoreTextAdditions.h */,
|
||||||
058D09EB195D050800B7D73C /* ASTextNodeCoreTextAdditions.m */,
|
058D09EB195D050800B7D73C /* ASTextNodeCoreTextAdditions.m */,
|
||||||
058D09EC195D050800B7D73C /* ASTextNodeRenderer.h */,
|
058D09EC195D050800B7D73C /* ASTextNodeRenderer.h */,
|
||||||
@@ -600,6 +611,7 @@
|
|||||||
058D0A4F195D05CB00B7D73C /* ASImageNode.h in Headers */,
|
058D0A4F195D05CB00B7D73C /* ASImageNode.h in Headers */,
|
||||||
058D0A50195D05CB00B7D73C /* ASImageNode.mm in Headers */,
|
058D0A50195D05CB00B7D73C /* ASImageNode.mm in Headers */,
|
||||||
058D0A51195D05CB00B7D73C /* ASTextNode.h in Headers */,
|
058D0A51195D05CB00B7D73C /* ASTextNode.h in Headers */,
|
||||||
|
296A0A2E1A9516B2005ACEAA /* ASBatchFetching.h in Headers */,
|
||||||
058D0A52195D05CB00B7D73C /* ASTextNode.mm in Headers */,
|
058D0A52195D05CB00B7D73C /* ASTextNode.mm in Headers */,
|
||||||
055F1A3819ABD413004DAFF1 /* ASRangeController.h in Headers */,
|
055F1A3819ABD413004DAFF1 /* ASRangeController.h in Headers */,
|
||||||
292C59A31A956527007E5DD6 /* ASRangeHandlerRender.h in Headers */,
|
292C59A31A956527007E5DD6 /* ASRangeHandlerRender.h in Headers */,
|
||||||
@@ -832,6 +844,7 @@
|
|||||||
058D0A29195D050800B7D73C /* ASDisplayNode+DebugTiming.mm in Sources */,
|
058D0A29195D050800B7D73C /* ASDisplayNode+DebugTiming.mm in Sources */,
|
||||||
058D0A22195D050800B7D73C /* _ASAsyncTransaction.m in Sources */,
|
058D0A22195D050800B7D73C /* _ASAsyncTransaction.m in Sources */,
|
||||||
055F1A3919ABD413004DAFF1 /* ASRangeController.mm in Sources */,
|
055F1A3919ABD413004DAFF1 /* ASRangeController.mm in Sources */,
|
||||||
|
296A0A2F1A9516B2005ACEAA /* ASBatchFetching.m in Sources */,
|
||||||
D785F6631A74327E00291744 /* ASScrollNode.m in Sources */,
|
D785F6631A74327E00291744 /* ASScrollNode.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@@ -841,6 +854,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */,
|
2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */,
|
||||||
|
296A0A351A951ABF005ACEAA /* ASBatchFetchingTests.m in Sources */,
|
||||||
058D0A3E195D057000B7D73C /* ASTextNodeRendererTests.m in Sources */,
|
058D0A3E195D057000B7D73C /* ASTextNodeRendererTests.m in Sources */,
|
||||||
058D0A3D195D057000B7D73C /* ASTextNodeCoreTextAdditionsTests.m in Sources */,
|
058D0A3D195D057000B7D73C /* ASTextNodeCoreTextAdditionsTests.m in Sources */,
|
||||||
058D0A3C195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m in Sources */,
|
058D0A3C195D057000B7D73C /* ASMutableAttributedStringBuilderTests.m in Sources */,
|
||||||
|
|||||||
@@ -185,7 +185,7 @@
|
|||||||
* If not implemented, the collectionView assumes that it should notify its asyncDelegate when batch fetching
|
* If not implemented, the collectionView assumes that it should notify its asyncDelegate when batch fetching
|
||||||
* should occur.
|
* should occur.
|
||||||
*/
|
*/
|
||||||
- (BOOL)shouldBatchFetchForCollectionView:(UICollectionView *)collectionView;
|
- (BOOL)shouldBatchFetchForCollectionView:(ASCollectionView *)collectionView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receive a message that the collectionView is near the end of its data set and more data should be fetched if
|
* Receive a message that the collectionView is near the end of its data set and more data should be fetched if
|
||||||
@@ -200,7 +200,7 @@
|
|||||||
* UICollectionView currently only supports batch events for tail loads. If you require a head load, consider
|
* UICollectionView currently only supports batch events for tail loads. If you require a head load, consider
|
||||||
* implementing a UIRefreshControl.
|
* implementing a UIRefreshControl.
|
||||||
*/
|
*/
|
||||||
- (void)collectionView:(UICollectionView *)collectionView beginBatchFetchingWithContext:(ASBatchContext *)context;
|
- (void)collectionView:(ASCollectionView *)collectionView beginBatchFetchingWithContext:(ASBatchContext *)context;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#import "ASRangeController.h"
|
#import "ASRangeController.h"
|
||||||
#import "ASDataController.h"
|
#import "ASDataController.h"
|
||||||
#import "ASDisplayNodeInternal.h"
|
#import "ASDisplayNodeInternal.h"
|
||||||
|
#import "ASBatchFetching.h"
|
||||||
|
|
||||||
const static NSUInteger kASCollectionViewAnimationNone = 0;
|
const static NSUInteger kASCollectionViewAnimationNone = 0;
|
||||||
|
|
||||||
@@ -144,6 +145,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
|
|
||||||
_batchContext = [[ASBatchContext alloc] init];
|
_batchContext = [[ASBatchContext alloc] init];
|
||||||
|
|
||||||
|
_leadingScreensForBatching = 1.0;
|
||||||
|
|
||||||
_proxyDelegate = [[_ASCollectionViewProxy alloc] initWithTarget:nil interceptor:self];
|
_proxyDelegate = [[_ASCollectionViewProxy alloc] initWithTarget:nil interceptor:self];
|
||||||
super.delegate = (id<UICollectionViewDelegate>)_proxyDelegate;
|
super.delegate = (id<UICollectionViewDelegate>)_proxyDelegate;
|
||||||
|
|
||||||
@@ -386,7 +389,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
if ([self.asyncDelegate respondsToSelector:@selector(shouldBatchFetchForCollectionView:)]) {
|
if ([self.asyncDelegate respondsToSelector:@selector(shouldBatchFetchForCollectionView:)]) {
|
||||||
return [self.asyncDelegate shouldBatchFetchForCollectionView:self];
|
return [self.asyncDelegate shouldBatchFetchForCollectionView:self];
|
||||||
} else {
|
} else {
|
||||||
return YES;
|
// if the delegate does not respond to this method, there is no point in starting to fetch
|
||||||
|
return [self.asyncDelegate respondsToSelector:@selector(collectionView:beginBatchFetchingWithContext:)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,32 +398,11 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
{
|
{
|
||||||
ASDisplayNodeAssert(_batchContext != nil, @"Batch context should exist");
|
ASDisplayNodeAssert(_batchContext != nil, @"Batch context should exist");
|
||||||
|
|
||||||
// Bail if we are already fetching, the delegate doesn't care, or we're told not to fetch
|
if (![self shouldFetchBatch]) {
|
||||||
if ([_batchContext isFetching] ||
|
|
||||||
![self.asyncDelegate respondsToSelector:@selector(collectionView:beginBatchFetchingWithContext:)] ||
|
|
||||||
![self shouldFetchBatch]) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASScrollDirection scrollDirection = [self scrollDirection];
|
if (ASDisplayShouldFetchBatchForContext(_batchContext, [self scrollDirection], self.bounds, self.contentSize, targetOffset, _leadingScreensForBatching)) {
|
||||||
CGFloat viewSize, offset, contentSize;
|
|
||||||
|
|
||||||
if (scrollDirection == ASScrollDirectionUp) {
|
|
||||||
viewSize = CGRectGetHeight(self.bounds);
|
|
||||||
offset = targetOffset.y;
|
|
||||||
contentSize = self.contentSize.height;
|
|
||||||
} else { // horizontal
|
|
||||||
viewSize = CGRectGetWidth(self.bounds);
|
|
||||||
offset = targetOffset.x;
|
|
||||||
contentSize = self.contentSize.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
CGFloat triggerDistance = viewSize * _leadingScreensForBatching;
|
|
||||||
|
|
||||||
// Determine if the offset that we are headed to is within the number of screens we have defined
|
|
||||||
// ASCollectionView supports tail loading only currently, hence the check against Up and Left
|
|
||||||
BOOL supportedBatchScrollDirection = scrollDirection == ASScrollDirectionUp || ASScrollDirectionLeft;
|
|
||||||
if (supportedBatchScrollDirection && contentSize - (viewSize + offset) <= triggerDistance) {
|
|
||||||
[_batchContext beginBatchFetching];
|
[_batchContext beginBatchFetching];
|
||||||
[self.asyncDelegate collectionView:self beginBatchFetchingWithContext:_batchContext];
|
[self.asyncDelegate collectionView:self beginBatchFetchingWithContext:_batchContext];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,7 +190,7 @@
|
|||||||
* If not implemented, the tableView assumes that it should notify its asyncDelegate when batch fetching
|
* If not implemented, the tableView assumes that it should notify its asyncDelegate when batch fetching
|
||||||
* should occur.
|
* should occur.
|
||||||
*/
|
*/
|
||||||
- (BOOL)shouldBatchFetchForTableView:(UITableView *)tableView;
|
- (BOOL)shouldBatchFetchForTableView:(ASTableView *)tableView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receive a message that the tableView is near the end of its data set and more data should be fetched if necessary.
|
* Receive a message that the tableView is near the end of its data set and more data should be fetched if necessary.
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
* ASTableView currently only supports batch events for tail loads. If you require a head load, consider implementing a
|
* ASTableView currently only supports batch events for tail loads. If you require a head load, consider implementing a
|
||||||
* UIRefreshControl.
|
* UIRefreshControl.
|
||||||
*/
|
*/
|
||||||
- (void)tableView:(UITableView *)tableView beginBatchFetchingWithContext:(ASBatchContext *)context;
|
- (void)tableView:(ASTableView *)tableView beginBatchFetchingWithContext:(ASBatchContext *)context;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
#import "ASLayoutController.h"
|
#import "ASLayoutController.h"
|
||||||
#import "ASRangeController.h"
|
#import "ASRangeController.h"
|
||||||
#import "ASDisplayNodeInternal.h"
|
#import "ASDisplayNodeInternal.h"
|
||||||
|
#import "ASBatchFetching.h"
|
||||||
|
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
@@ -395,7 +395,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
if ([self.asyncDelegate respondsToSelector:@selector(shouldBatchFetchForTableView:)]) {
|
if ([self.asyncDelegate respondsToSelector:@selector(shouldBatchFetchForTableView:)]) {
|
||||||
return [self.asyncDelegate shouldBatchFetchForTableView:self];
|
return [self.asyncDelegate shouldBatchFetchForTableView:self];
|
||||||
} else {
|
} else {
|
||||||
return YES;
|
// if the delegate does not respond to this method, there is no point in starting to fetch
|
||||||
|
return [self.asyncDelegate respondsToSelector:@selector(tableView:beginBatchFetchingWithContext:)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,22 +404,11 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
{
|
{
|
||||||
ASDisplayNodeAssert(_batchContext != nil, @"Batch context should exist");
|
ASDisplayNodeAssert(_batchContext != nil, @"Batch context should exist");
|
||||||
|
|
||||||
// Bail if we are already fetching, the delegate doesn't care, or we're told not to fetch
|
if (![self shouldFetchBatch]) {
|
||||||
if ([_batchContext isFetching] ||
|
|
||||||
![self.asyncDelegate respondsToSelector:@selector(tableView:beginBatchFetchingWithContext:)] ||
|
|
||||||
![self shouldFetchBatch]) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGFloat viewHeight = CGRectGetHeight(self.bounds);
|
if (ASDisplayShouldFetchBatchForContext(_batchContext, [self scrollDirection], self.bounds, self.contentSize, targetOffset, _leadingScreensForBatching)) {
|
||||||
CGFloat triggerDistance = viewHeight * _leadingScreensForBatching;
|
|
||||||
CGFloat offset = targetOffset.y;
|
|
||||||
CGFloat contentHeight = self.contentSize.height;
|
|
||||||
|
|
||||||
// Determine if the offset that we are headed to is within the number of screens we have defined
|
|
||||||
// ASTableView supports tail loading only currently, hence the check against ASScrollDirectionUp
|
|
||||||
if ([self scrollDirection] == ASScrollDirectionUp &&
|
|
||||||
contentHeight - (viewHeight + offset) <= triggerDistance) {
|
|
||||||
[_batchContext beginBatchFetching];
|
[_batchContext beginBatchFetching];
|
||||||
[self.asyncDelegate tableView:self beginBatchFetchingWithContext:_batchContext];
|
[self.asyncDelegate tableView:self beginBatchFetchingWithContext:_batchContext];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract A context object to notify when batch fetches are finished or cancelled.
|
* @abstract A context object to notify when batch fetches are finished or cancelled.
|
||||||
*/
|
*/
|
||||||
@@ -29,8 +31,6 @@
|
|||||||
*/
|
*/
|
||||||
- (void)completeBatchFetching:(BOOL)didComplete;
|
- (void)completeBatchFetching:(BOOL)didComplete;
|
||||||
|
|
||||||
- (void)beginBatchFetching;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask the context object if the batch fetching process was cancelled by the context owner.
|
* Ask the context object if the batch fetching process was cancelled by the context owner.
|
||||||
*
|
*
|
||||||
@@ -49,4 +49,12 @@
|
|||||||
*/
|
*/
|
||||||
- (void)cancelBatchFetching;
|
- (void)cancelBatchFetching;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the context object that fetching has started.
|
||||||
|
*
|
||||||
|
* @discussion Call this method only when you are beginning a fetch process. This should really only be called by the
|
||||||
|
* context object's owner. Calling this method should be complimented with -completeBatchFetching:.
|
||||||
|
*/
|
||||||
|
- (void)beginBatchFetching;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
36
AsyncDisplayKit/Details/ASBatchFetching.h
Normal file
36
AsyncDisplayKit/Details/ASBatchFetching.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
#import "ASBatchContext.h"
|
||||||
|
#import "ASScrollDirection.h"
|
||||||
|
#import "ASBaseDefines.h"
|
||||||
|
|
||||||
|
ASDISPLAYNODE_EXTERN_C_BEGIN
|
||||||
|
|
||||||
|
/**
|
||||||
|
@abstract Determine if batch fetching should begin based on the state of the parameters.
|
||||||
|
@param context The batch fetching context that contains knowledge about in-flight fetches.
|
||||||
|
@param scrollDirection The current scrolling direction of the scroll view.
|
||||||
|
@param bounds The bounds of the scrollview.
|
||||||
|
@param contentSize The content size of the scrollview.
|
||||||
|
@param targetOffset The offset that the scrollview will scroll to.
|
||||||
|
@param leadingScreens How many screens in the remaining distance will trigger batch fetching.
|
||||||
|
@return Whether or not the current state should proceed with batch fetching.
|
||||||
|
@discussion This method is broken into a category for unit testing purposes and should be used with the ASTableView and
|
||||||
|
* ASCollectionView batch fetching API.
|
||||||
|
*/
|
||||||
|
extern BOOL ASDisplayShouldFetchBatchForContext(ASBatchContext *context,
|
||||||
|
ASScrollDirection scrollDirection,
|
||||||
|
CGRect bounds,
|
||||||
|
CGSize contentSize,
|
||||||
|
CGPoint targetOffset,
|
||||||
|
CGFloat leadingScreens);
|
||||||
|
|
||||||
|
ASDISPLAYNODE_EXTERN_C_END
|
||||||
51
AsyncDisplayKit/Details/ASBatchFetching.m
Normal file
51
AsyncDisplayKit/Details/ASBatchFetching.m
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "ASBatchFetching.h"
|
||||||
|
|
||||||
|
BOOL ASDisplayShouldFetchBatchForContext(ASBatchContext *context,
|
||||||
|
ASScrollDirection scrollDirection,
|
||||||
|
CGRect bounds,
|
||||||
|
CGSize contentSize,
|
||||||
|
CGPoint targetOffset,
|
||||||
|
CGFloat leadingScreens) {
|
||||||
|
// do not allow fetching if a batch is already in-flight and hasn't been completed or cancelled
|
||||||
|
if ([context isFetching]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no fetching for null states
|
||||||
|
if (leadingScreens <= 0.0 ||
|
||||||
|
CGPointEqualToPoint(targetOffset, CGPointZero) ||
|
||||||
|
CGSizeEqualToSize(contentSize, CGSizeZero) ||
|
||||||
|
CGRectEqualToRect(bounds, CGRectZero)) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only Up and Left scrolls are currently supported (tail loading)
|
||||||
|
if (scrollDirection != ASScrollDirectionUp && scrollDirection != ASScrollDirectionLeft) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat viewLength, offset, contentLength;
|
||||||
|
|
||||||
|
if (scrollDirection == ASScrollDirectionUp) {
|
||||||
|
viewLength = bounds.size.height;
|
||||||
|
offset = targetOffset.y;
|
||||||
|
contentLength = contentSize.height;
|
||||||
|
} else { // horizontal
|
||||||
|
viewLength = bounds.size.width;
|
||||||
|
offset = targetOffset.x;
|
||||||
|
contentLength = contentSize.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat triggerDistance = viewLength * leadingScreens;
|
||||||
|
CGFloat remainingDistance = contentLength - viewLength - offset;
|
||||||
|
|
||||||
|
return remainingDistance <= triggerDistance;
|
||||||
|
}
|
||||||
@@ -10,20 +10,14 @@
|
|||||||
|
|
||||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||||
#import <AsyncDisplayKit/ASLayoutRangeType.h>
|
#import <AsyncDisplayKit/ASLayoutRangeType.h>
|
||||||
|
#import "ASScrollDirection.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
CGFloat leadingBufferScreenfuls;
|
CGFloat leadingBufferScreenfuls;
|
||||||
CGFloat trailingBufferScreenfuls;
|
CGFloat trailingBufferScreenfuls;
|
||||||
} ASRangeTuningParameters;
|
} ASRangeTuningParameters;
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, ASScrollDirection) {
|
|
||||||
ASScrollDirectionNone,
|
|
||||||
ASScrollDirectionRight,
|
|
||||||
ASScrollDirectionLeft,
|
|
||||||
ASScrollDirectionUp,
|
|
||||||
ASScrollDirectionDown,
|
|
||||||
};
|
|
||||||
|
|
||||||
@protocol ASLayoutController <NSObject>
|
@protocol ASLayoutController <NSObject>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
17
AsyncDisplayKit/Details/ASScrollDirection.h
Normal file
17
AsyncDisplayKit/Details/ASScrollDirection.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
typedef NS_ENUM(NSInteger, ASScrollDirection) {
|
||||||
|
ASScrollDirectionNone,
|
||||||
|
ASScrollDirectionRight,
|
||||||
|
ASScrollDirectionLeft,
|
||||||
|
ASScrollDirectionUp,
|
||||||
|
ASScrollDirectionDown,
|
||||||
|
};
|
||||||
102
AsyncDisplayKitTests/ASBatchFetchingTests.m
Normal file
102
AsyncDisplayKitTests/ASBatchFetchingTests.m
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/* Copyright (c) 2014-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <XCTest/XCTest.h>
|
||||||
|
|
||||||
|
#import "ASBatchFetching.h"
|
||||||
|
|
||||||
|
@interface ASBatchFetchingTests : XCTestCase
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ASBatchFetchingTests
|
||||||
|
|
||||||
|
#define PASSING_RECT (CGRect){0,0,1,1}
|
||||||
|
#define PASSING_SIZE (CGSize){1,1}
|
||||||
|
#define PASSING_POINT (CGPoint){1,1}
|
||||||
|
#define VERTICAL_RECT(h) (CGRect){0,0,0,h}
|
||||||
|
#define VERTICAL_SIZE(h) (CGSize){0,h}
|
||||||
|
#define VERTICAL_OFFSET(y) (CGPoint){0,y}
|
||||||
|
#define HORIZONTAL_RECT(w) (CGRect){0,0,w,0}
|
||||||
|
#define HORIZONTAL_SIZE(w) (CGSize){w,0}
|
||||||
|
#define HORIZONTAL_OFFSET(x) (CGPoint){x,0}
|
||||||
|
|
||||||
|
- (void)testBatchNullState {
|
||||||
|
ASBatchContext *context = [[ASBatchContext alloc] init];
|
||||||
|
BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionUp, CGRectZero, CGSizeZero, CGPointZero, 0.0);
|
||||||
|
XCTAssert(shouldFetch == NO, @"Should not fetch in the null state");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testBatchAlreadyFetching {
|
||||||
|
ASBatchContext *context = [[ASBatchContext alloc] init];
|
||||||
|
[context beginBatchFetching];
|
||||||
|
BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionUp, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0);
|
||||||
|
XCTAssert(shouldFetch == NO, @"Should not fetch when context is already fetching");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testUnsupportedScrollDirections {
|
||||||
|
ASBatchContext *context = [[ASBatchContext alloc] init];
|
||||||
|
BOOL fetchRight = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionRight, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0);
|
||||||
|
XCTAssert(fetchRight == NO, @"Should not fetch for scrolling right");
|
||||||
|
BOOL fetchDown = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionDown, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0);
|
||||||
|
XCTAssert(fetchDown == NO, @"Should not fetch for scrolling down");
|
||||||
|
BOOL fetchUp = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionUp, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0);
|
||||||
|
XCTAssert(fetchUp == YES, @"Should fetch for scrolling up");
|
||||||
|
BOOL fetchLeft = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionLeft, PASSING_RECT, PASSING_SIZE, PASSING_POINT, 1.0);
|
||||||
|
XCTAssert(fetchLeft == YES, @"Should fetch for scrolling left");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testVerticalScrollToExactLeading {
|
||||||
|
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, ASScrollDirectionUp, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 1.0), 1.0);
|
||||||
|
XCTAssert(shouldFetch == YES, @"Fetch should begin when vertically scrolling to exactly 1 leading screen away");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testVerticalScrollToLessThanLeading {
|
||||||
|
CGFloat screen = 1.0;
|
||||||
|
ASBatchContext *context = [[ASBatchContext alloc] init];
|
||||||
|
// 3 screens of content, scroll only 1/2 of one screen
|
||||||
|
BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionUp, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 0.5), 1.0);
|
||||||
|
XCTAssert(shouldFetch == NO, @"Fetch should not begin when vertically scrolling less than the leading distance away");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testVerticalScrollingPastContentSize {
|
||||||
|
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, ASScrollDirectionUp, VERTICAL_RECT(screen), VERTICAL_SIZE(screen * 3.0), VERTICAL_OFFSET(screen * 3.0), 1.0);
|
||||||
|
XCTAssert(shouldFetch == YES, @"Fetch should begin when vertically scrolling past the content size");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testHorizontalScrollToExactLeading {
|
||||||
|
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, ASScrollDirectionLeft, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 1.0), 1.0);
|
||||||
|
XCTAssert(shouldFetch == YES, @"Fetch should begin when horizontally scrolling to exactly 1 leading screen away");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testHorizontalScrollToLessThanLeading {
|
||||||
|
CGFloat screen = 1.0;
|
||||||
|
ASBatchContext *context = [[ASBatchContext alloc] init];
|
||||||
|
// 3 screens of content, scroll only 1/2 of one screen
|
||||||
|
BOOL shouldFetch = ASDisplayShouldFetchBatchForContext(context, ASScrollDirectionRight, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 0.5), 1.0);
|
||||||
|
XCTAssert(shouldFetch == NO, @"Fetch should not begin when horizontally scrolling less than the leading distance away");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testHorizontalScrollingPastContentSize {
|
||||||
|
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, ASScrollDirectionUp, HORIZONTAL_RECT(screen), HORIZONTAL_SIZE(screen * 3.0), HORIZONTAL_OFFSET(screen * 3.0), 1.0);
|
||||||
|
XCTAssert(shouldFetch == YES, @"Fetch should begin when vertically scrolling past the content size");
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
Reference in New Issue
Block a user