mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-16 19:30:29 +00:00
Stub out ASCollectionDataController subclass
This commit is contained in:
parent
e492770aed
commit
e9eadac4ae
@ -11,7 +11,7 @@
|
||||
#import "ASAssert.h"
|
||||
#import "ASCollectionViewLayoutController.h"
|
||||
#import "ASRangeController.h"
|
||||
#import "ASDataController.h"
|
||||
#import "ASCollectionDataController.h"
|
||||
#import "ASDisplayNodeInternal.h"
|
||||
#import "ASBatchFetching.h"
|
||||
#import "UICollectionViewLayout+ASConvenience.h"
|
||||
@ -37,9 +37,7 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
// handled by ASCollectionView node<->cell machinery
|
||||
sel == @selector(collectionView:cellForItemAtIndexPath:) ||
|
||||
sel == @selector(collectionView:layout:sizeForItemAtIndexPath:) ||
|
||||
|
||||
// TODO: Supplementary views are currently not supported. An assertion is triggered if the _asyncDataSource implements this method.
|
||||
// sel == @selector(collectionView:viewForSupplementaryElementOfKind:atIndexPath:) ||
|
||||
sel == @selector(collectionView:viewForSupplementaryElementOfKind:atIndexPath:) ||
|
||||
|
||||
// handled by ASRangeController
|
||||
sel == @selector(numberOfSectionsInCollectionView:) ||
|
||||
@ -136,7 +134,7 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
_ASCollectionViewProxy *_proxyDataSource;
|
||||
_ASCollectionViewProxy *_proxyDelegate;
|
||||
|
||||
ASDataController *_dataController;
|
||||
ASCollectionDataController *_dataController;
|
||||
ASRangeController *_rangeController;
|
||||
ASCollectionViewLayoutController *_layoutController;
|
||||
|
||||
@ -201,7 +199,7 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
_rangeController.delegate = self;
|
||||
_rangeController.layoutController = _layoutController;
|
||||
|
||||
_dataController = [[ASDataController alloc] initWithAsyncDataFetching:asyncDataFetchingEnabled];
|
||||
_dataController = [[ASCollectionDataController alloc] initWithAsyncDataFetching:asyncDataFetchingEnabled];
|
||||
_dataController.delegate = _rangeController;
|
||||
_dataController.dataSource = self;
|
||||
|
||||
@ -381,8 +379,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
|
||||
- (void)registerSupplementaryViewOfKind:(NSString *)elementKind
|
||||
{
|
||||
NSString *identifier = [NSString stringWithFormat:@"_ASCollectionSupplementaryView_%@", elementKind];
|
||||
[self registerClass:[UIView class] forSupplementaryViewOfKind:elementKind withReuseIdentifier:identifier];
|
||||
[self registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:elementKind
|
||||
withReuseIdentifier:[self __reuseIdentifierForKind:elementKind]];
|
||||
}
|
||||
|
||||
- (void)insertSections:(NSIndexSet *)sections
|
||||
@ -433,6 +431,16 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
[_dataController moveRowAtIndexPath:indexPath toIndexPath:newIndexPath withAnimationOptions:kASCollectionViewAnimationNone];
|
||||
}
|
||||
|
||||
- (ASCellNode *)nodeForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [_dataController nodeAtIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (NSString *)__reuseIdentifierForKind:(NSString *)kind
|
||||
{
|
||||
return [NSString stringWithFormat:@"_ASCollectionSupplementaryView_%@", kind];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Intercepted selectors.
|
||||
|
||||
@ -443,7 +451,8 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
_ASCollectionViewCell *cell = [self dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
|
||||
|
||||
ASCellNode *node = [_dataController nodeAtIndexPath:indexPath];
|
||||
[_rangeController configureContentView:cell.contentView forCellNode:node];
|
||||
|
||||
[_rangeController configureContentView:cell.contentView forNode:node];
|
||||
|
||||
cell.node = node;
|
||||
|
||||
@ -455,6 +464,15 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
return [[_dataController nodeAtIndexPath:indexPath] calculatedSize];
|
||||
}
|
||||
|
||||
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSString *identifier = [self __reuseIdentifierForKind:kind];
|
||||
UICollectionReusableView *view = [self dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:identifier forIndexPath:indexPath];
|
||||
ASDisplayNode *node = [_dataController supplementaryNodeOfKind:kind atIndexPath:indexPath];
|
||||
[_rangeController configureContentView:view forNode:node];
|
||||
return view;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
|
||||
{
|
||||
_superIsPendingDataLoad = NO;
|
||||
@ -613,6 +631,11 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
return node;
|
||||
}
|
||||
|
||||
- (ASDisplayNode *)dataController:(ASDataController *)dataController supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [_asyncDataSource collectionView:self nodeForSupplementaryElementOfKind:kind atIndexPath:indexPath];
|
||||
}
|
||||
|
||||
- (ASSizeRange)dataController:(ASDataController *)dataController constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASSizeRange constrainedSize;
|
||||
@ -659,7 +682,7 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
return [_asyncDataSource collectionView:self numberOfItemsInSection:section];
|
||||
}
|
||||
|
||||
- (NSUInteger)dataControllerNumberOfSections:(ASDataController *)dataController {
|
||||
- (NSUInteger)numberOfSectionsInDataController:(ASDataController *)dataController {
|
||||
if ([_asyncDataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)]) {
|
||||
return [_asyncDataSource numberOfSectionsInCollectionView:self];
|
||||
} else {
|
||||
|
||||
@ -530,7 +530,7 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
||||
}
|
||||
|
||||
ASCellNode *node = [_dataController nodeAtIndexPath:indexPath];
|
||||
[_rangeController configureContentView:cell.contentView forCellNode:node];
|
||||
[_rangeController configureContentView:cell.contentView forNode:node];
|
||||
|
||||
cell.node = node;
|
||||
cell.backgroundColor = node.backgroundColor;
|
||||
@ -859,7 +859,7 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
||||
return [_asyncDataSource tableView:self numberOfRowsInSection:section];
|
||||
}
|
||||
|
||||
- (NSUInteger)dataControllerNumberOfSections:(ASDataController *)dataController
|
||||
- (NSUInteger)numberOfSectionsInDataController:(ASDataController *)dataController
|
||||
{
|
||||
if ([_asyncDataSource respondsToSelector:@selector(numberOfSectionsInTableView:)]) {
|
||||
return [_asyncDataSource numberOfSectionsInTableView:self];
|
||||
|
||||
26
AsyncDisplayKit/Details/ASCollectionDataController.h
Normal file
26
AsyncDisplayKit/Details/ASCollectionDataController.h
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// ASCollectionDataController.h
|
||||
// Pods
|
||||
//
|
||||
// Created by Levi McCallum on 9/22/15.
|
||||
//
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/ASDataController.h>
|
||||
|
||||
@class ASDisplayNode, ASCollectionDataController;
|
||||
@protocol ASDataControllerSource;
|
||||
|
||||
@protocol ASCollectionDataControllerSource <ASDataControllerSource>
|
||||
|
||||
- (ASDisplayNode *)dataController:(ASDataController *)dataController supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (NSArray *)supplementaryKindsInDataController:(ASCollectionDataController *)dataController;
|
||||
|
||||
@end
|
||||
|
||||
@interface ASCollectionDataController : ASDataController
|
||||
|
||||
- (ASDisplayNode *)supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
@end
|
||||
72
AsyncDisplayKit/Details/ASCollectionDataController.m
Normal file
72
AsyncDisplayKit/Details/ASCollectionDataController.m
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// ASCollectionDataController.m
|
||||
// Pods
|
||||
//
|
||||
// Created by Levi McCallum on 9/22/15.
|
||||
//
|
||||
//
|
||||
|
||||
#import "ASCollectionDataController.h"
|
||||
|
||||
#import "ASAssert.h"
|
||||
|
||||
@interface ASDataController (Subclasses)
|
||||
|
||||
/**
|
||||
* Queues the given operation until an `endUpdates` synchronize update is completed.
|
||||
*
|
||||
* If this method is called outside of a begin/endUpdates batch update, the block is
|
||||
* executed immediately.
|
||||
*/
|
||||
- (void)performEditCommandWithBlock:(void (^)(void))block;
|
||||
|
||||
/**
|
||||
* Safely locks access to the data source and executes the given block, unlocking once complete.
|
||||
*
|
||||
* When `asyncDataFetching` is enabled, the block is executed on a background thread.
|
||||
*/
|
||||
- (void)accessDataSourceWithBlock:(dispatch_block_t)block;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASCollectionDataController {
|
||||
NSMutableDictionary *_completedSupplementaryNodes;
|
||||
NSMutableDictionary *_editingSupplementaryNodes;
|
||||
}
|
||||
|
||||
- (void)initialSupplementaryLoading
|
||||
{
|
||||
[self performEditCommandWithBlock:^{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
[self accessDataSourceWithBlock:^{
|
||||
NSArray *elementKinds = [self.collectionDataSource supplementaryKindsInDataController:self];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (ASDisplayNode *)supplementaryNodeOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
return _completedSupplementaryNodes[kind][indexPath.section][indexPath.item];
|
||||
}
|
||||
|
||||
- (id<ASCollectionDataControllerSource>)collectionDataSource
|
||||
{
|
||||
return (id<ASCollectionDataControllerSource>)self.dataSource;
|
||||
}
|
||||
|
||||
#pragma mark - Internal Data Querying
|
||||
|
||||
- (void)_insertNodes:(NSArray *)nodes ofKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths
|
||||
{
|
||||
if (indexPaths.count == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
- (void)_deleteNodesOfKind:(NSString *)kind atIndexPaths:(NSArray *)indexPaths
|
||||
{
|
||||
if (indexPaths.count == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
@end
|
||||
@ -40,7 +40,7 @@ typedef NSUInteger ASDataControllerAnimationOptions;
|
||||
/**
|
||||
Fetch the number of sections.
|
||||
*/
|
||||
- (NSUInteger)dataControllerNumberOfSections:(ASDataController *)dataController;
|
||||
- (NSUInteger)numberOfSectionsInDataController:(ASDataController *)dataController;
|
||||
|
||||
/**
|
||||
Lock the data source for data fetching.
|
||||
|
||||
@ -239,7 +239,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
ASDisplayNodeAssertMainThread();
|
||||
[self accessDataSourceWithBlock:^{
|
||||
NSMutableArray *indexPaths = [NSMutableArray array];
|
||||
NSUInteger sectionNum = [_dataSource dataControllerNumberOfSections:self];
|
||||
NSUInteger sectionNum = [_dataSource numberOfSectionsInDataController:self];
|
||||
|
||||
// insert sections
|
||||
[self insertSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionNum)] withAnimationOptions:0];
|
||||
@ -266,7 +266,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
[_editingTransactionQueue waitUntilAllOperationsAreFinished];
|
||||
|
||||
[self accessDataSourceWithBlock:^{
|
||||
NSUInteger sectionCount = [_dataSource dataControllerNumberOfSections:self];
|
||||
NSUInteger sectionCount = [_dataSource numberOfSectionsInDataController:self];
|
||||
NSMutableArray *updatedNodes = [NSMutableArray array];
|
||||
NSMutableArray *updatedIndexPaths = [NSMutableArray array];
|
||||
[self _populateFromEntireDataSourceWithMutableNodes:updatedNodes mutableIndexPaths:updatedIndexPaths];
|
||||
@ -335,7 +335,7 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
|
||||
- (void)_populateFromEntireDataSourceWithMutableNodes:(NSMutableArray *)nodes mutableIndexPaths:(NSMutableArray *)indexPaths
|
||||
{
|
||||
NSUInteger sectionNum = [_dataSource dataControllerNumberOfSections:self];
|
||||
NSUInteger sectionNum = [_dataSource numberOfSectionsInDataController:self];
|
||||
for (NSUInteger i = 0; i < sectionNum; i++) {
|
||||
NSIndexPath *sectionIndexPath = [[NSIndexPath alloc] initWithIndex:i];
|
||||
|
||||
|
||||
@ -41,9 +41,9 @@
|
||||
*
|
||||
* @param contentView UIView to add a (sized) node's view to.
|
||||
*
|
||||
* @param node The ASCellNode to be added.
|
||||
* @param node The node to be added. Often an ASCellNode.
|
||||
*/
|
||||
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)node;
|
||||
- (void)configureContentView:(UIView *)contentView forNode:(ASDisplayNode *)node;
|
||||
|
||||
/**
|
||||
* Delegate and ultimate data source. Must not be nil.
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
|
||||
#pragma mark - View manipulation
|
||||
|
||||
- (void)moveNode:(ASCellNode *)node toView:(UIView *)view
|
||||
- (void)moveNode:(ASDisplayNode *)node toView:(UIView *)view
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(node, @"Cannot move a nil node to a view");
|
||||
@ -158,7 +158,7 @@
|
||||
return rangeType == ASLayoutRangeTypeRender;
|
||||
}
|
||||
|
||||
- (void)configureContentView:(UIView *)contentView forCellNode:(ASCellNode *)cellNode
|
||||
- (void)configureContentView:(UIView *)contentView forNode:(ASDisplayNode *)cellNode
|
||||
{
|
||||
if (cellNode.view.superview == contentView) {
|
||||
// this content view is already correctly configured
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
// This happens if the UITableViewCell is reused after scrolling offscreen. Because the node has already been given the opportunity to display, we do not
|
||||
// proactively re-host it within the workingWindow (improving efficiency). Some time later, it may fall outside the working range, in which case calling
|
||||
// -recursivelyClearContents is critical. If the user scrolls back and it is re-hosted in a UITableViewCell, the content will still exist as it is not cleared
|
||||
// by simply being removed from the cell. The code that usually triggers this condition is the -removeFromSuperview in -[ASRangeController configureContentView:forCellNode:].
|
||||
// by simply being removed from the cell. The code that usually triggers this condition is the -removeFromSuperview in -[ASRangeController configureContentView:forNode:].
|
||||
// Condition #4 is suboptimal in some cases, as it is conceivable that memory warnings could trigger clearing content that is inside the working range. However, enforcing the
|
||||
// preservation of this content could result in the app being killed, which is not likely preferable over briefly seeing placeholders in the event the user scrolls backwards.
|
||||
// Nonetheless, future changes to the implementation will likely eliminate this behavior to simplify debugging and extensibility of working range functionality.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user