mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-31 10:20:15 +00:00
Add batch animation
This commit is contained in:
@@ -213,7 +213,7 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
|
||||
- (void)beginUpdates
|
||||
{
|
||||
[self throwUnimplementedException];
|
||||
[_dataController beginUpdates];
|
||||
}
|
||||
|
||||
- (void)endUpdates
|
||||
@@ -223,17 +223,17 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
|
||||
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
|
||||
{
|
||||
[_dataController insertSections:sections];
|
||||
[_dataController insertSections:sections withAnimationOption:animation];
|
||||
}
|
||||
|
||||
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
|
||||
{
|
||||
[_dataController deleteSections:sections];
|
||||
[_dataController deleteSections:sections withAnimationOption:animation];
|
||||
}
|
||||
|
||||
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
|
||||
{
|
||||
[_dataController reloadSections:sections];
|
||||
[_dataController reloadSections:sections withAnimationOption:animation];
|
||||
}
|
||||
|
||||
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection
|
||||
@@ -243,17 +243,17 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
|
||||
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
|
||||
{
|
||||
[_dataController insertRowsAtIndexPaths:indexPaths];
|
||||
[_dataController insertRowsAtIndexPaths:indexPaths withAnimationOption:animation];
|
||||
}
|
||||
|
||||
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
|
||||
{
|
||||
[_dataController deleteRowsAtIndexPaths:indexPaths];
|
||||
[_dataController deleteRowsAtIndexPaths:indexPaths withAnimationOption:animation];
|
||||
}
|
||||
|
||||
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
|
||||
{
|
||||
[_dataController reloadRowsAtIndexPaths:indexPaths];
|
||||
[_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOption:animation];
|
||||
}
|
||||
|
||||
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
|
||||
@@ -341,6 +341,16 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
#pragma mark -
|
||||
#pragma mark ASRangeControllerDelegate.
|
||||
|
||||
- (void)rangeControllerBeginUpdates:(ASRangeController *)rangeController {
|
||||
ASDisplayNodeAssertMainThread();
|
||||
[super beginUpdates];
|
||||
}
|
||||
|
||||
- (void)rangeControllerEndUpdates:(ASRangeController *)rangeController {
|
||||
ASDisplayNodeAssertMainThread();
|
||||
[super endUpdates];
|
||||
}
|
||||
|
||||
- (NSArray *)rangeControllerVisibleNodeIndexPaths:(ASRangeController *)rangeController
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
@@ -358,40 +368,40 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
return self.bounds.size;
|
||||
}
|
||||
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertNodesAtIndexPaths:(NSArray *)indexPaths
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[UIView performWithoutAnimation:^{
|
||||
[super insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
|
||||
}];
|
||||
// [UIView performWithoutAnimation:^{
|
||||
[super insertRowsAtIndexPaths:indexPaths withRowAnimation:(UITableViewRowAnimation)animationOption];
|
||||
// }];
|
||||
}
|
||||
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[UIView performWithoutAnimation:^{
|
||||
[super deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
|
||||
}];
|
||||
// [UIView performWithoutAnimation:^{
|
||||
[super deleteRowsAtIndexPaths:indexPaths withRowAnimation:(UITableViewRowAnimation)animationOption];
|
||||
// }];
|
||||
}
|
||||
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertSectionsAtIndexSet:(NSIndexSet *)indexSet
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[UIView performWithoutAnimation:^{
|
||||
[super insertSections:indexSet withRowAnimation:UITableViewRowAnimationNone];
|
||||
}];
|
||||
// [UIView performWithoutAnimation:^{
|
||||
[super insertSections:indexSet withRowAnimation:(UITableViewRowAnimation)animationOption];
|
||||
// }];
|
||||
}
|
||||
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
[UIView performWithoutAnimation:^{
|
||||
[super deleteSections:indexSet withRowAnimation:UITableViewRowAnimationNone];
|
||||
}];
|
||||
// [UIView performWithoutAnimation:^{
|
||||
[super deleteSections:indexSet withRowAnimation:(UITableViewRowAnimation)animationOption];
|
||||
// }];
|
||||
}
|
||||
|
||||
#pragma mark - ASDataControllerDelegate
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
@class ASCellNode;
|
||||
@class ASDataController;
|
||||
|
||||
typedef NSUInteger ASDataControllerAnimationOptions;
|
||||
|
||||
/**
|
||||
Data source for data controller
|
||||
It will be invoked in the same thread as the api call of ASDataController.
|
||||
@@ -42,29 +44,35 @@
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Called for batch update.
|
||||
*/
|
||||
- (void)dataControllerBeginUpdates:(ASDataController *)dataController;
|
||||
- (void)dataControllerEndUpdates:(ASDataController *)dataController;
|
||||
|
||||
/**
|
||||
Called for insertion of elements.
|
||||
*/
|
||||
- (void)dataController:(ASDataController *)dataController willInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)dataController:(ASDataController *)dataController didInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)dataController:(ASDataController *)dataController willInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
- (void)dataController:(ASDataController *)dataController didInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
Called for deletion of elements.
|
||||
*/
|
||||
- (void)dataController:(ASDataController *)dataController willDeleteNodesAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)dataController:(ASDataController *)dataController willDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
Called for insertion of sections.
|
||||
*/
|
||||
- (void)dataController:(ASDataController *)dataController willInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet;
|
||||
- (void)dataController:(ASDataController *)dataController didInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet;
|
||||
- (void)dataController:(ASDataController *)dataController willInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
- (void)dataController:(ASDataController *)dataController didInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
Called for deletion of sections.
|
||||
*/
|
||||
- (void)dataController:(ASDataController *)dataController willDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet;
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet;
|
||||
- (void)dataController:(ASDataController *)dataController willDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
@end
|
||||
|
||||
@@ -94,19 +102,23 @@
|
||||
|
||||
/** @name Data Updating */
|
||||
|
||||
- (void)insertSections:(NSIndexSet *)sections;
|
||||
- (void)beginUpdates;
|
||||
|
||||
- (void)deleteSections:(NSIndexSet *)sections;
|
||||
- (void)endUpdates;
|
||||
|
||||
- (void)reloadSections:(NSIndexSet *)sections;
|
||||
- (void)insertSections:(NSIndexSet *)sections withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
- (void)deleteSections:(NSIndexSet *)sections withAnimationOption:(ASDataControllerAnimationOptions)animationOption;;
|
||||
|
||||
- (void)reloadSections:(NSIndexSet *)sections withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;
|
||||
|
||||
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;
|
||||
|
||||
|
||||
@@ -8,48 +8,49 @@
|
||||
#import "ASCellNode.h"
|
||||
#import "ASDisplayNode.h"
|
||||
#import "ASMultidimensionalArrayUtils.h"
|
||||
#import "ASDisplayNodeInternal.h"
|
||||
|
||||
#define INSERT_NODES(multidimensionalArray, indexPath, elements) \
|
||||
#define INSERT_NODES(multidimensionalArray, indexPath, elements, animationOption) \
|
||||
{ \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:willInsertNodes:atIndexPaths:)]) { \
|
||||
[_delegate dataController:self willInsertNodes:elements atIndexPaths:indexPath]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:willInsertNodes:atIndexPaths:withAnimationOption:)]) { \
|
||||
[_delegate dataController:self willInsertNodes:elements atIndexPaths:indexPath withAnimationOption:animationOption]; \
|
||||
} \
|
||||
ASInsertElementsIntoMultidimensionalArrayAtIndexPaths(multidimensionalArray, indexPath, elements); \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:didInsertNodes:atIndexPaths:)]) { \
|
||||
[_delegate dataController:self didInsertNodes:elements atIndexPaths:indexPath]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:didInsertNodes:atIndexPaths:withAnimationOption:)]) { \
|
||||
[_delegate dataController:self didInsertNodes:elements atIndexPaths:indexPath withAnimationOption:animationOption]; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DELETE_NODES(multidimensionalArray, indexPath) \
|
||||
#define DELETE_NODES(multidimensionalArray, indexPath, animationOption) \
|
||||
{ \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:willDeleteNodesAtIndexPaths:)]) { \
|
||||
[_delegate dataController:self willDeleteNodesAtIndexPaths:indexPath]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:willDeleteNodesAtIndexPaths:withAnimationOption:)]) { \
|
||||
[_delegate dataController:self willDeleteNodesAtIndexPaths:indexPath withAnimationOption:animationOption]; \
|
||||
} \
|
||||
ASDeleteElementsInMultidimensionalArrayAtIndexPaths(multidimensionalArray, indexPath); \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:didDeleteNodesAtIndexPaths:)]) { \
|
||||
[_delegate dataController:self didDeleteNodesAtIndexPaths:indexPath]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:didDeleteNodesAtIndexPaths:withAnimationOption:)]) { \
|
||||
[_delegate dataController:self didDeleteNodesAtIndexPaths:indexPath withAnimationOption:animationOption]; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define INSERT_SECTIONS(multidimensionalArray, indexSet, sections) \
|
||||
#define INSERT_SECTIONS(multidimensionalArray, indexSet, sections, animationOption) \
|
||||
{ \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:willInsertSections:atIndexSet:)]) { \
|
||||
[_delegate dataController:self willInsertSections:sections atIndexSet:indexSet]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:willInsertSections:atIndexSet:withAnimationOption:)]) { \
|
||||
[_delegate dataController:self willInsertSections:sections atIndexSet:indexSet withAnimationOption:animationOption]; \
|
||||
} \
|
||||
[multidimensionalArray insertObjects:sections atIndexes:indexSet]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:didInsertSections:atIndexSet:)]) { \
|
||||
[_delegate dataController:self didInsertSections:sections atIndexSet:indexSet]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:didInsertSections:atIndexSet:withAnimationOption:)]) { \
|
||||
[_delegate dataController:self didInsertSections:sections atIndexSet:indexSet withAnimationOption:animationOption]; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DELETE_SECTIONS(multidimensionalArray, indexSet) \
|
||||
#define DELETE_SECTIONS(multidimensionalArray, indexSet, animationOption) \
|
||||
{ \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:willDeleteSectionsAtIndexSet:)]) { \
|
||||
[_delegate dataController:self willDeleteSectionsAtIndexSet:indexSet]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:willDeleteSectionsAtIndexSet:withAnimationOption:)]) { \
|
||||
[_delegate dataController:self willDeleteSectionsAtIndexSet:indexSet withAnimationOption:animationOption]; \
|
||||
} \
|
||||
[multidimensionalArray removeObjectsAtIndexes:indexSet]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:didDeleteSectionsAtIndexSet:)]) { \
|
||||
[_delegate dataController:self didDeleteSectionsAtIndexSet:indexSet]; \
|
||||
if ([_delegate respondsToSelector:@selector(dataController:didDeleteSectionsAtIndexSet:withAnimationOption:)]) { \
|
||||
[_delegate dataController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOption:animationOption]; \
|
||||
} \
|
||||
}
|
||||
|
||||
@@ -70,6 +71,7 @@
|
||||
#define ENABLE_BACKGROUND_UPDATE 0
|
||||
|
||||
const static NSUInteger kASDataControllerSizingCountPerProcessor = 5;
|
||||
const static NSUInteger kASDataControllerAnimationOptionNone = 0;
|
||||
|
||||
static void *kASSizingQueueContext = &kASSizingQueueContext;
|
||||
static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
@@ -78,6 +80,8 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
NSMutableArray *_nodes;
|
||||
}
|
||||
|
||||
@property (atomic, assign) NSUInteger batchUpdateCounter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASDataController
|
||||
@@ -85,6 +89,7 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_nodes = [NSMutableArray array];
|
||||
_batchUpdateCounter = 0;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -187,7 +192,7 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
NSUInteger sectionNum = [_dataSource dataControllerNumberOfSections:self];
|
||||
|
||||
// insert sections
|
||||
[self insertSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionNum)]];
|
||||
[self insertSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, sectionNum)] withAnimationOption:0];
|
||||
|
||||
for (NSUInteger i = 0; i < sectionNum; i++) {
|
||||
NSIndexPath *indexPath = [[NSIndexPath alloc] initWithIndex:i];
|
||||
@@ -199,12 +204,30 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
}
|
||||
|
||||
// insert elements
|
||||
[self insertRowsAtIndexPaths:indexPaths];
|
||||
[self insertRowsAtIndexPaths:indexPaths withAnimationOption:kASDataControllerAnimationOptionNone];
|
||||
}
|
||||
|
||||
#pragma mark - Data Update
|
||||
|
||||
- (void)insertSections:(NSIndexSet *)indexSet {
|
||||
- (void)beginUpdates {
|
||||
dispatch_async([[self class] sizingQueue], ^{
|
||||
[self asyncUpdateDataWithBlock:^{
|
||||
_batchUpdateCounter++;
|
||||
[_delegate dataControllerBeginUpdates:self];
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)endUpdates {
|
||||
dispatch_async([[self class] sizingQueue], ^{
|
||||
[self asyncUpdateDataWithBlock:^{
|
||||
_batchUpdateCounter--;
|
||||
[_delegate dataControllerEndUpdates:self];
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)insertSections:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
__block int nodeTotalCnt = 0;
|
||||
NSMutableArray *nodeCounts = [NSMutableArray arrayWithCapacity:indexSet.count];
|
||||
[indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
|
||||
@@ -235,26 +258,26 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
for (NSUInteger i = 0; i < indexSet.count; i++) {
|
||||
[sectionArray addObject:[NSMutableArray array]];
|
||||
}
|
||||
INSERT_SECTIONS(_nodes , indexSet, sectionArray);
|
||||
INSERT_SECTIONS(_nodes , indexSet, sectionArray, animationOption);
|
||||
}];
|
||||
|
||||
[self _batchInsertNodes:nodes atIndexPaths:indexPaths];
|
||||
[self _batchInsertNodes:nodes atIndexPaths:indexPaths withAnimationOptions:animationOption];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)deleteSections:(NSIndexSet *)indexSet {
|
||||
- (void)deleteSections:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
dispatch_async([[self class] sizingQueue], ^{
|
||||
[self asyncUpdateDataWithBlock:^{
|
||||
// remove elements
|
||||
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet(_nodes, indexSet);
|
||||
|
||||
DELETE_NODES(_nodes, indexPaths);
|
||||
DELETE_SECTIONS(_nodes, indexSet);
|
||||
DELETE_NODES(_nodes, indexPaths, animationOption);
|
||||
DELETE_SECTIONS(_nodes, indexSet, animationOption);
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)reloadSections:(NSIndexSet *)sections {
|
||||
- (void)reloadSections:(NSIndexSet *)sections withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
// We need to keep data query on data source in the calling thread.
|
||||
NSMutableArray *updatedIndexPaths = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *updatedNodes = [[NSMutableArray alloc] init];
|
||||
@@ -274,11 +297,11 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
[self syncUpdateDataWithBlock:^{
|
||||
// remove elements
|
||||
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet(_nodes, sections);
|
||||
DELETE_NODES(_nodes, indexPaths);
|
||||
DELETE_NODES(_nodes, indexPaths, animationOption);
|
||||
}];
|
||||
|
||||
// reinsert the elements
|
||||
[self _batchInsertNodes:updatedNodes atIndexPaths:updatedIndexPaths];
|
||||
[self _batchInsertNodes:updatedNodes atIndexPaths:updatedIndexPaths withAnimationOptions:animationOption];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -288,7 +311,7 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
// remove elements
|
||||
NSArray *indexPaths = ASIndexPathsForMultidimensionalArrayAtIndexSet(_nodes, [NSIndexSet indexSetWithIndex:section]);
|
||||
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(_nodes, indexPaths);
|
||||
DELETE_NODES(_nodes, indexPaths);
|
||||
DELETE_NODES(_nodes, indexPaths, kASDataControllerAnimationOptionNone);
|
||||
|
||||
// update the section of indexpaths
|
||||
NSIndexPath *sectionIndexPath = [[NSIndexPath alloc] initWithIndex:newSection];
|
||||
@@ -298,13 +321,14 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
}];
|
||||
|
||||
// Don't re-calculate size for moving
|
||||
INSERT_NODES(_nodes, updatedIndexPaths, nodes);
|
||||
INSERT_NODES(_nodes, updatedIndexPaths, nodes, kASDataControllerAnimationOptionNone);
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)_insertNodes:(NSArray *)nodes
|
||||
atIndexPaths:(NSArray *)indexPaths {
|
||||
atIndexPaths:(NSArray *)indexPaths
|
||||
withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
if (!nodes.count) {
|
||||
return;
|
||||
}
|
||||
@@ -333,7 +357,7 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
|
||||
[self asyncUpdateDataWithBlock:^{
|
||||
// updating the cells
|
||||
INSERT_NODES(_nodes, indexPaths, nodes);
|
||||
INSERT_NODES(_nodes, indexPaths, nodes, animationOption);
|
||||
}];
|
||||
};
|
||||
|
||||
@@ -345,7 +369,8 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
}
|
||||
|
||||
- (void)_batchInsertNodes:(NSArray *)nodes
|
||||
atIndexPaths:(NSArray *)indexPaths {
|
||||
atIndexPaths:(NSArray *)indexPaths
|
||||
withAnimationOptions:(ASDataControllerAnimationOptions)animationOption {
|
||||
NSUInteger blockSize = [[ASDataController class] parallelProcessorCount] * kASDataControllerSizingCountPerProcessor;
|
||||
|
||||
// Processing in batches
|
||||
@@ -354,11 +379,11 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
NSArray *batchedIndexPaths = [indexPaths subarrayWithRange:batchedRange];
|
||||
NSArray *batchedNodes = [nodes subarrayWithRange:batchedRange];
|
||||
|
||||
[self _insertNodes:batchedNodes atIndexPaths:batchedIndexPaths];
|
||||
[self _insertNodes:batchedNodes atIndexPaths:batchedIndexPaths withAnimationOption:animationOption];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths {
|
||||
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
// sort indexPath to avoid messing up the index when inserting in several batches
|
||||
NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)];
|
||||
NSMutableArray *nodes = [[NSMutableArray alloc] initWithCapacity:indexPaths.count];
|
||||
@@ -366,21 +391,21 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
[nodes addObject:[_dataSource dataController:self nodeAtIndexPath:sortedIndexPaths[i]]];
|
||||
}
|
||||
|
||||
[self _batchInsertNodes:nodes atIndexPaths:indexPaths];
|
||||
[self _batchInsertNodes:nodes atIndexPaths:indexPaths withAnimationOptions:animationOption];
|
||||
}
|
||||
|
||||
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths {
|
||||
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
// sort indexPath in order to avoid messing up the index when deleting
|
||||
NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)];
|
||||
|
||||
dispatch_async([ASDataController sizingQueue], ^{
|
||||
[self asyncUpdateDataWithBlock:^{
|
||||
DELETE_NODES(_nodes, sortedIndexPaths);
|
||||
DELETE_NODES(_nodes, sortedIndexPaths, animationOption);
|
||||
}];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths {
|
||||
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
// The reloading operation required reloading the data
|
||||
// Loading data in the calling thread
|
||||
NSMutableArray *nodes = [[NSMutableArray alloc] initWithCapacity:indexPaths.count];
|
||||
@@ -391,10 +416,10 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
|
||||
dispatch_async([ASDataController sizingQueue], ^{
|
||||
[self syncUpdateDataWithBlock:^{
|
||||
DELETE_NODES(_nodes, indexPaths);
|
||||
DELETE_NODES(_nodes, indexPaths, animationOption);
|
||||
}];
|
||||
|
||||
[self _batchInsertNodes:nodes atIndexPaths:indexPaths];
|
||||
[self _batchInsertNodes:nodes atIndexPaths:indexPaths withAnimationOptions:animationOption];
|
||||
});
|
||||
}
|
||||
|
||||
@@ -403,11 +428,11 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
[self asyncUpdateDataWithBlock:^{
|
||||
NSArray *nodes = ASFindElementsInMultidimensionalArrayAtIndexPaths(_nodes, [NSArray arrayWithObject:indexPath]);
|
||||
NSArray *indexPaths = [NSArray arrayWithObject:indexPath];
|
||||
DELETE_NODES(_nodes, indexPaths);
|
||||
DELETE_NODES(_nodes, indexPaths, kASDataControllerAnimationOptionNone);
|
||||
|
||||
// Don't re-calculate size for moving
|
||||
NSArray *newIndexPaths = [NSArray arrayWithObject:newIndexPath];
|
||||
INSERT_NODES(_nodes, newIndexPaths, nodes);
|
||||
INSERT_NODES(_nodes, newIndexPaths, nodes, kASDataControllerAnimationOptionNone);
|
||||
}];
|
||||
});
|
||||
}
|
||||
@@ -433,10 +458,10 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
[self syncUpdateDataWithBlock:^{
|
||||
|
||||
NSArray *indexPaths = ASIndexPathsForMultidimensionalArray(_nodes);
|
||||
DELETE_NODES(_nodes, indexPaths);
|
||||
DELETE_NODES(_nodes, indexPaths, kASDataControllerAnimationOptionNone);
|
||||
|
||||
NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, _nodes.count)];
|
||||
DELETE_SECTIONS(_nodes, indexSet);
|
||||
DELETE_SECTIONS(_nodes, indexSet, kASDataControllerAnimationOptionNone);
|
||||
|
||||
|
||||
// Insert section
|
||||
@@ -446,11 +471,11 @@ static void *kASDataUpdatingQueueContext = &kASDataUpdatingQueueContext;
|
||||
[sections addObject:[[NSMutableArray alloc] init]];
|
||||
}
|
||||
|
||||
INSERT_SECTIONS(_nodes, [[NSMutableIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, sectionNum)], sections);
|
||||
INSERT_SECTIONS(_nodes, [[NSMutableIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, sectionNum)], sections, kASDataControllerAnimationOptionNone);
|
||||
|
||||
}];
|
||||
|
||||
[self _batchInsertNodes:updatedNodes atIndexPaths:updatedIndexPaths];
|
||||
[self _batchInsertNodes:updatedNodes atIndexPaths:updatedIndexPaths withAnimationOptions:kASDataControllerAnimationOptionNone];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,16 @@
|
||||
*/
|
||||
- (CGSize)rangeControllerViewportSize:(ASRangeController *)rangeController;
|
||||
|
||||
/**
|
||||
* Begin updates.
|
||||
*/
|
||||
- (void)rangeControllerBeginUpdates:(ASRangeController *)rangeController;
|
||||
|
||||
/**
|
||||
* End updates.
|
||||
*/
|
||||
- (void)rangeControllerEndUpdates:(ASRangeController * )rangeController;
|
||||
|
||||
/**
|
||||
* Fetch nodes at specific index paths.
|
||||
*/
|
||||
@@ -78,43 +88,43 @@
|
||||
/**
|
||||
* Called for nodes insertion.
|
||||
*/
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertNodesAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
* Called for nodes deletion.
|
||||
*/
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
* Called for section insertion.
|
||||
*/
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertSectionsAtIndexSet:(NSIndexSet *)indexSet;
|
||||
- (void)rangeController:(ASRangeController *)rangeController didInsertSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
* Called for section deletion.
|
||||
*/
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet;
|
||||
- (void)rangeController:(ASRangeController *)rangeController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
* Called before nodes insertion.
|
||||
*/
|
||||
- (void)rangeController:(ASRangeController *)rangeController willInsertNodesAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)rangeController:(ASRangeController *)rangeController willInsertNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
* Called before nodes deletion.
|
||||
*/
|
||||
- (void)rangeController:(ASRangeController *)rangeController willDeleteNodesAtIndexPaths:(NSArray *)indexPaths;
|
||||
- (void)rangeController:(ASRangeController *)rangeController willDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
* Called before section insertion.
|
||||
*/
|
||||
- (void)rangeController:(ASRangeController *)rangeController willInsertSectionsAtIndexSet:(NSIndexSet *)indexSet;
|
||||
- (void)rangeController:(ASRangeController *)rangeController willInsertSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
/**
|
||||
* Called before section deletion.
|
||||
*/
|
||||
- (void)rangeController:(ASRangeController *)rangeController willDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet;
|
||||
- (void)rangeController:(ASRangeController *)rangeController willDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption;
|
||||
|
||||
@end
|
||||
|
||||
@@ -213,15 +213,27 @@
|
||||
|
||||
#pragma mark - ASDataControllerDelegete
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController willInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths {
|
||||
- (void)dataControllerBeginUpdates:(ASDataController *)dataController {
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
if ([_delegate respondsToSelector:@selector(rangeController:willInsertNodesAtIndexPaths:)]) {
|
||||
[_delegate rangeController:self willInsertNodesAtIndexPaths:indexPaths];
|
||||
[_delegate rangeControllerBeginUpdates:self];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataControllerEndUpdates:(ASDataController *)dataController {
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
[_delegate rangeControllerEndUpdates:self];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController willInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
if ([_delegate respondsToSelector:@selector(rangeController:willInsertNodesAtIndexPaths:withAnimationOption:)]) {
|
||||
[_delegate rangeController:self willInsertNodesAtIndexPaths:indexPaths withAnimationOption:animationOption];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController didInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths {
|
||||
- (void)dataController:(ASDataController *)dataController didInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
ASDisplayNodeAssert(nodes.count == indexPaths.count, @"Invalid index path");
|
||||
|
||||
NSMutableArray *nodeSizes = [NSMutableArray arrayWithCapacity:nodes.count];
|
||||
@@ -231,36 +243,36 @@
|
||||
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
[_layoutController insertNodesAtIndexPaths:indexPaths withSizes:nodeSizes];
|
||||
[_delegate rangeController:self didInsertNodesAtIndexPaths:indexPaths];
|
||||
[_delegate rangeController:self didInsertNodesAtIndexPaths:indexPaths withAnimationOption:animationOption];
|
||||
_workingRangeIsValid = NO;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController willDeleteNodesAtIndexPaths:(NSArray *)indexPaths {
|
||||
- (void)dataController:(ASDataController *)dataController willDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
if ([_delegate respondsToSelector:@selector(rangeController:willDeleteNodesAtIndexPaths:)]) {
|
||||
[_delegate rangeController:self didDeleteNodesAtIndexPaths:indexPaths];
|
||||
if ([_delegate respondsToSelector:@selector(rangeController:willDeleteNodesAtIndexPaths:withAnimationOption:)]) {
|
||||
[_delegate rangeController:self didDeleteNodesAtIndexPaths:indexPaths withAnimationOption:animationOption];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths {
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteNodesAtIndexPaths:(NSArray *)indexPaths withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
[_layoutController deleteNodesAtIndexPaths:indexPaths];
|
||||
[_delegate rangeController:self didDeleteNodesAtIndexPaths:indexPaths];
|
||||
[_delegate rangeController:self didDeleteNodesAtIndexPaths:indexPaths withAnimationOption:animationOption];
|
||||
_workingRangeIsValid = NO;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController willInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet {
|
||||
- (void)dataController:(ASDataController *)dataController willInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
if ([_delegate respondsToSelector:@selector(rangeController:willInsertSectionsAtIndexSet:)]) {
|
||||
[_delegate rangeController:self willInsertSectionsAtIndexSet:indexSet];
|
||||
if ([_delegate respondsToSelector:@selector(rangeController:willInsertSectionsAtIndexSet:withAnimationOption:)]) {
|
||||
[_delegate rangeController:self willInsertSectionsAtIndexSet:indexSet withAnimationOption:animationOption];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController didInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet {
|
||||
- (void)dataController:(ASDataController *)dataController didInsertSections:(NSArray *)sections atIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
ASDisplayNodeAssert(sections.count == indexSet.count, @"Invalid sections");
|
||||
|
||||
NSMutableArray *sectionNodeSizes = [NSMutableArray arrayWithCapacity:sections.count];
|
||||
@@ -275,23 +287,23 @@
|
||||
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
[_layoutController insertSections:sectionNodeSizes atIndexSet:indexSet];
|
||||
[_delegate rangeController:self didInsertSectionsAtIndexSet:indexSet];
|
||||
[_delegate rangeController:self didInsertSectionsAtIndexSet:indexSet withAnimationOption:animationOption];
|
||||
_workingRangeIsValid = NO;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController willDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet {
|
||||
- (void)dataController:(ASDataController *)dataController willDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
if ([_delegate respondsToSelector:@selector(rangeController:willDeleteSectionsAtIndexSet:)]) {
|
||||
[_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet];
|
||||
[_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOption:animationOption];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet {
|
||||
- (void)dataController:(ASDataController *)dataController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOption:(ASDataControllerAnimationOptions)animationOption {
|
||||
ASDisplayNodePerformBlockOnMainThread(^{
|
||||
[_layoutController deleteSectionsAtIndexSet:indexSet];
|
||||
[_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet];
|
||||
[_delegate rangeController:self didDeleteSectionsAtIndexSet:indexSet withAnimationOption:animationOption];
|
||||
_workingRangeIsValid = NO;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user