mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
ASCollectionView batch API
This commit is contained in:
@@ -138,7 +138,6 @@
|
|||||||
05F20AA41A15733C00DCA68A /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
05F20AA41A15733C00DCA68A /* ASImageProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = 05F20AA31A15733C00DCA68A /* ASImageProtocols.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */; };
|
1950C4491A3BB5C1005C8279 /* ASEqualityHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */; };
|
||||||
2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.m */; };
|
2911485C1A77147A005D0878 /* ASControlNodeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2911485B1A77147A005D0878 /* ASControlNodeTests.m */; };
|
||||||
<<<<<<< HEAD
|
|
||||||
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C59991A956527007E5DD6 /* ASLayoutRangeType.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
292C599F1A956527007E5DD6 /* ASLayoutRangeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C59991A956527007E5DD6 /* ASLayoutRangeType.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
292C59A01A956527007E5DD6 /* ASRangeHandlerPreload.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C599A1A956527007E5DD6 /* ASRangeHandlerPreload.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
292C59A01A956527007E5DD6 /* ASRangeHandlerPreload.h in Headers */ = {isa = PBXBuildFile; fileRef = 292C599A1A956527007E5DD6 /* ASRangeHandlerPreload.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
292C59A11A956527007E5DD6 /* ASRangeHandlerPreload.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292C599B1A956527007E5DD6 /* ASRangeHandlerPreload.mm */; };
|
292C59A11A956527007E5DD6 /* ASRangeHandlerPreload.mm in Sources */ = {isa = PBXBuildFile; fileRef = 292C599B1A956527007E5DD6 /* ASRangeHandlerPreload.mm */; };
|
||||||
@@ -146,6 +145,7 @@
|
|||||||
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 */; };
|
||||||
|
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"; }; };
|
||||||
464052201A3F83C40061C0BA /* ASDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 464052191A3F83C40061C0BA /* ASDataController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
464052201A3F83C40061C0BA /* ASDataController.h in Headers */ = {isa = PBXBuildFile; fileRef = 464052191A3F83C40061C0BA /* ASDataController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
@@ -293,7 +293,6 @@
|
|||||||
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageProtocols.h; sourceTree = "<group>"; };
|
05F20AA31A15733C00DCA68A /* ASImageProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageProtocols.h; sourceTree = "<group>"; };
|
||||||
1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHelpers.h; sourceTree = "<group>"; };
|
1950C4481A3BB5C1005C8279 /* ASEqualityHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASEqualityHelpers.h; sourceTree = "<group>"; };
|
||||||
2911485B1A77147A005D0878 /* ASControlNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNodeTests.m; sourceTree = "<group>"; };
|
2911485B1A77147A005D0878 /* ASControlNodeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNodeTests.m; sourceTree = "<group>"; };
|
||||||
<<<<<<< HEAD
|
|
||||||
292C59991A956527007E5DD6 /* ASLayoutRangeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutRangeType.h; sourceTree = "<group>"; };
|
292C59991A956527007E5DD6 /* ASLayoutRangeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutRangeType.h; sourceTree = "<group>"; };
|
||||||
292C599A1A956527007E5DD6 /* ASRangeHandlerPreload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeHandlerPreload.h; sourceTree = "<group>"; };
|
292C599A1A956527007E5DD6 /* ASRangeHandlerPreload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASRangeHandlerPreload.h; sourceTree = "<group>"; };
|
||||||
292C599B1A956527007E5DD6 /* ASRangeHandlerPreload.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeHandlerPreload.mm; sourceTree = "<group>"; };
|
292C599B1A956527007E5DD6 /* ASRangeHandlerPreload.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASRangeHandlerPreload.mm; sourceTree = "<group>"; };
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#import <AsyncDisplayKit/ASRangeController.h>
|
#import <AsyncDisplayKit/ASRangeController.h>
|
||||||
#import <AsyncDisplayKit/ASCollectionViewProtocols.h>
|
#import <AsyncDisplayKit/ASCollectionViewProtocols.h>
|
||||||
#import <AsyncDisplayKit/ASBaseDefines.h>
|
#import <AsyncDisplayKit/ASBaseDefines.h>
|
||||||
|
#import <AsyncDisplayKit/ASBatchContext.h>
|
||||||
|
|
||||||
|
|
||||||
@class ASCellNode;
|
@class ASCellNode;
|
||||||
@@ -62,6 +63,13 @@
|
|||||||
*/
|
*/
|
||||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout asyncDataFetching:(BOOL)asyncDataFetchingEnabled;
|
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout asyncDataFetching:(BOOL)asyncDataFetchingEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of screens left to scroll before the delegate -collectionView:beginBatchFetchingWithContext: is called.
|
||||||
|
*
|
||||||
|
* Defaults to one screenful.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, assign) CGFloat leadingScreensForBatching;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload everything from scratch, destroying the working range and all cached nodes.
|
* Reload everything from scratch, destroying the working range and all cached nodes.
|
||||||
*
|
*
|
||||||
@@ -166,6 +174,34 @@
|
|||||||
- (void)collectionView:(ASCollectionView *)collectionView willDisplayNodeForItemAtIndexPath:(NSIndexPath *)indexPath;
|
- (void)collectionView:(ASCollectionView *)collectionView willDisplayNodeForItemAtIndexPath:(NSIndexPath *)indexPath;
|
||||||
- (void)collectionView:(ASCollectionView *)collectionView didEndDisplayingNodeForItemAtIndexPath:(NSIndexPath*)indexPath;
|
- (void)collectionView:(ASCollectionView *)collectionView didEndDisplayingNodeForItemAtIndexPath:(NSIndexPath*)indexPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the collectionView if batch fetching should begin.
|
||||||
|
*
|
||||||
|
* @param collectionView The sender.
|
||||||
|
*
|
||||||
|
* @discussion Use this method to conditionally fetch batches. Example use cases are: limiting the total number of
|
||||||
|
* objects that can be fetched or no network connection.
|
||||||
|
*
|
||||||
|
* If not implemented, the collectionView assumes that it should notify its asyncDelegate when batch fetching
|
||||||
|
* should occur.
|
||||||
|
*/
|
||||||
|
- (BOOL)shouldBatchFetchForCollectionView:(UICollectionView *)collectionView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive a message that the collectionView is near the end of its data set and more data should be fetched if
|
||||||
|
* necessary.
|
||||||
|
*
|
||||||
|
* @param tableView The sender.
|
||||||
|
* @param context A context object that must be notified when the batch fetch is completed.
|
||||||
|
*
|
||||||
|
* @discussion You must eventually call -completeBatchFetching: with an argument of YES in order to receive future
|
||||||
|
* notifications to do batch fetches.
|
||||||
|
*
|
||||||
|
* UICollectionView currently only supports batch events for tail loads. If you require a head load, consider
|
||||||
|
* implementing a UIRefreshControl.
|
||||||
|
*/
|
||||||
|
- (void)collectionView:(UICollectionView *)collectionView beginBatchFetchingWithContext:(ASBatchContext *)context;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface ASCollectionView (Deprecated)
|
@interface ASCollectionView (Deprecated)
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
|
|
||||||
// used for ASRangeController visibility updates
|
// used for ASRangeController visibility updates
|
||||||
sel == @selector(collectionView:willDisplayCell:forItemAtIndexPath:) ||
|
sel == @selector(collectionView:willDisplayCell:forItemAtIndexPath:) ||
|
||||||
sel == @selector(collectionView:didEndDisplayingCell:forItemAtIndexPath:)
|
sel == @selector(collectionView:didEndDisplayingCell:forItemAtIndexPath:) ||
|
||||||
|
|
||||||
|
// used for batch fetching API
|
||||||
|
sel == @selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,6 +106,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
NSMutableArray *_batchUpdateBlocks;
|
NSMutableArray *_batchUpdateBlocks;
|
||||||
|
|
||||||
BOOL _asyncDataFetchingEnabled;
|
BOOL _asyncDataFetchingEnabled;
|
||||||
|
|
||||||
|
ASBatchContext *_batchContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (atomic, assign) BOOL asyncDataSourceLocked;
|
@property (atomic, assign) BOOL asyncDataSourceLocked;
|
||||||
@@ -137,6 +142,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
_dataController.delegate = _rangeController;
|
_dataController.delegate = _rangeController;
|
||||||
_dataController.dataSource = self;
|
_dataController.dataSource = self;
|
||||||
|
|
||||||
|
_batchContext = [[ASBatchContext alloc] init];
|
||||||
|
|
||||||
_proxyDelegate = [[_ASCollectionViewProxy alloc] initWithTarget:nil interceptor:self];
|
_proxyDelegate = [[_ASCollectionViewProxy alloc] initWithTarget:nil interceptor:self];
|
||||||
super.delegate = (id<UICollectionViewDelegate>)_proxyDelegate;
|
super.delegate = (id<UICollectionViewDelegate>)_proxyDelegate;
|
||||||
|
|
||||||
@@ -362,6 +369,63 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark Batch Fetching
|
||||||
|
|
||||||
|
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
|
||||||
|
{
|
||||||
|
[self handleBatchFetchScrollingToOffset:*targetContentOffset];
|
||||||
|
|
||||||
|
if ([_asyncDelegate respondsToSelector:@selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:)]) {
|
||||||
|
[_asyncDelegate scrollViewWillEndDragging:scrollView withVelocity:velocity targetContentOffset:targetContentOffset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)shouldFetchBatch
|
||||||
|
{
|
||||||
|
if ([self.asyncDelegate respondsToSelector:@selector(shouldBatchFetchForCollectionView:)]) {
|
||||||
|
return [self.asyncDelegate shouldBatchFetchForCollectionView:self];
|
||||||
|
} else {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleBatchFetchScrollingToOffset:(CGPoint)targetOffset
|
||||||
|
{
|
||||||
|
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 ([_batchContext isFetching] ||
|
||||||
|
![self.asyncDelegate respondsToSelector:@selector(collectionView:beginBatchFetchingWithContext:)] ||
|
||||||
|
![self shouldFetchBatch]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASScrollDirection scrollDirection = [self scrollDirection];
|
||||||
|
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];
|
||||||
|
[self.asyncDelegate collectionView:self beginBatchFetchingWithContext:_batchContext];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - ASDataControllerSource
|
#pragma mark - ASDataControllerSource
|
||||||
|
|
||||||
- (ASCellNode *)dataController:(ASDataController *)dataController nodeAtIndexPath:(NSIndexPath *)indexPath
|
- (ASCellNode *)dataController:(ASDataController *)dataController nodeAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
|||||||
@@ -64,7 +64,7 @@
|
|||||||
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style asyncDataFetching:(BOOL)asyncDataFetchingEnabled;
|
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style asyncDataFetching:(BOOL)asyncDataFetchingEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of screens left to scroll before the delegate -tableView:shouldBeginBatchFetchingWithContext: is called.
|
* The number of screens left to scroll before the delegate -tableView:beginBatchFetchingWithContext: is called.
|
||||||
*
|
*
|
||||||
* Defaults to one screenful.
|
* Defaults to one screenful.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -401,6 +401,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
|||||||
|
|
||||||
- (void)handleBatchFetchScrollingToOffset:(CGPoint)targetOffset
|
- (void)handleBatchFetchScrollingToOffset:(CGPoint)targetOffset
|
||||||
{
|
{
|
||||||
|
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
|
// Bail if we are already fetching, the delegate doesn't care, or we're told not to fetch
|
||||||
if ([_batchContext isFetching] ||
|
if ([_batchContext isFetching] ||
|
||||||
![self.asyncDelegate respondsToSelector:@selector(tableView:beginBatchFetchingWithContext:)] ||
|
![self.asyncDelegate respondsToSelector:@selector(tableView:beginBatchFetchingWithContext:)] ||
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
|
|
||||||
- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath
|
- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||||
{
|
{
|
||||||
NSString *text = [NSString stringWithFormat:@"[%ld.%ld] says hi", indexPath.section, indexPath.item];
|
NSString *text = [NSString stringWithFormat:@"[%zd.%zd] says hi", indexPath.section, indexPath.item];
|
||||||
ASTextCellNode *node = [[ASTextCellNode alloc] init];
|
ASTextCellNode *node = [[ASTextCellNode alloc] init];
|
||||||
node.text = text;
|
node.text = text;
|
||||||
node.backgroundColor = [UIColor lightGrayColor];
|
node.backgroundColor = [UIColor lightGrayColor];
|
||||||
@@ -78,13 +78,21 @@
|
|||||||
return 300;
|
return 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)collectionViewLockDataSource:(ASCollectionView *)collectionView {
|
- (void)collectionViewLockDataSource:(ASCollectionView *)collectionView
|
||||||
|
{
|
||||||
// lock the data source
|
// lock the data source
|
||||||
// The data source should not be change until it is unlocked.
|
// The data source should not be change until it is unlocked.
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)collectionViewUnlockDataSource:(ASCollectionView *)collectionView {
|
- (void)collectionViewUnlockDataSource:(ASCollectionView *)collectionView
|
||||||
|
{
|
||||||
// unlock the data source to enable data source updating.
|
// unlock the data source to enable data source updating.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)collectionView:(UICollectionView *)collectionView beginBatchFetchingWithContext:(ASBatchContext *)context
|
||||||
|
{
|
||||||
|
NSLog(@"fetch additional content");
|
||||||
|
[context completeBatchFetching:YES];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
Reference in New Issue
Block a user