From 263bb311f2cfd0f7c5b718d3f3c26f52b3b38eaa Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Wed, 27 Jan 2016 10:50:30 -0800 Subject: [PATCH 1/3] expose beginUpdates and endUpdates --- AsyncDisplayKit/ASCollectionNode+Beta.h | 2 ++ AsyncDisplayKit/ASCollectionNode.mm | 10 ++++++++++ AsyncDisplayKit/ASCollectionView.mm | 5 +++++ AsyncDisplayKit/Details/ASCollectionInternal.h | 2 ++ 4 files changed, 19 insertions(+) diff --git a/AsyncDisplayKit/ASCollectionNode+Beta.h b/AsyncDisplayKit/ASCollectionNode+Beta.h index 11ea3ac2fd..e05e740ba2 100644 --- a/AsyncDisplayKit/ASCollectionNode+Beta.h +++ b/AsyncDisplayKit/ASCollectionNode+Beta.h @@ -14,6 +14,8 @@ NS_ASSUME_NONNULL_BEGIN @interface ASCollectionNode (Beta) - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(nullable id)layoutFacilitator; +- (void)beginUpdates; +- (void)endUpdatesAnimated:(BOOL)animated; @end diff --git a/AsyncDisplayKit/ASCollectionNode.mm b/AsyncDisplayKit/ASCollectionNode.mm index 5bed1a1bbf..204c434621 100644 --- a/AsyncDisplayKit/ASCollectionNode.mm +++ b/AsyncDisplayKit/ASCollectionNode.mm @@ -187,6 +187,16 @@ [self.view clearFetchedData]; } +- (void)beginUpdates +{ + [self.view.dataController beginUpdates]; +} + +- (void)endUpdatesAnimated:(BOOL)animated +{ + [self.view.dataController endUpdatesAnimated:animated completion:nil]; +} + #pragma mark - ASCollectionView Forwards - (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 2b588d088b..62294e3415 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -396,6 +396,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; #pragma mark Assertions. +- (ASDataController *)dataController +{ + return _dataController; +} + - (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completion:(void (^)(BOOL))completion { ASDisplayNodeAssertMainThread(); diff --git a/AsyncDisplayKit/Details/ASCollectionInternal.h b/AsyncDisplayKit/Details/ASCollectionInternal.h index a0aff1e573..5bf70dfd35 100644 --- a/AsyncDisplayKit/Details/ASCollectionInternal.h +++ b/AsyncDisplayKit/Details/ASCollectionInternal.h @@ -8,11 +8,13 @@ #import "ASCollectionView.h" #import "ASCollectionNode.h" +#import "ASDataController.h" #import "ASRangeController.h" @interface ASCollectionView () - (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id)layoutFacilitator ownedByNode:(BOOL)ownedByNode; +@property (nonatomic, strong, readonly) ASDataController *dataController; @property (nonatomic, weak, readwrite) ASCollectionNode *collectionNode; @property (nonatomic, strong, readonly) ASRangeController *rangeController; @end From f6be279c60ddd54c51b4f0e3966114a17a2fa485 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Wed, 27 Jan 2016 12:50:41 -0800 Subject: [PATCH 2/3] Added more facilitator methods --- AsyncDisplayKit/ASCollectionNode.mm | 4 ++-- AsyncDisplayKit/ASCollectionView.mm | 14 +++++++++---- ...SCollectionViewLayoutFacilitatorProtocol.h | 21 +++++++++++++++++++ .../Details/ASCollectionInternal.h | 2 +- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/AsyncDisplayKit/ASCollectionNode.mm b/AsyncDisplayKit/ASCollectionNode.mm index 204c434621..3d5c3d9288 100644 --- a/AsyncDisplayKit/ASCollectionNode.mm +++ b/AsyncDisplayKit/ASCollectionNode.mm @@ -189,12 +189,12 @@ - (void)beginUpdates { - [self.view.dataController beginUpdates]; + [self.view.dataController beginUpdates]; } - (void)endUpdatesAnimated:(BOOL)animated { - [self.view.dataController endUpdatesAnimated:animated completion:nil]; + [self.view.dataController endUpdatesAnimated:animated completion:nil]; } #pragma mark - ASCollectionView Forwards diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 62294e3415..7cae446342 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -398,7 +398,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; - (ASDataController *)dataController { - return _dataController; + return _dataController; } - (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completion:(void (^)(BOOL))completion @@ -856,6 +856,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } ASPerformBlockWithoutAnimation(!animated, ^{ + [_layoutFacilitator collectionViewWillPerformBatchUpdates]; [super performBatchUpdates:^{ for (dispatch_block_t block in _batchUpdateBlocks) { block(); @@ -870,17 +871,18 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; - (void)rangeController:(ASRangeController *)rangeController didInsertNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions { ASDisplayNodeAssertMainThread(); - [_layoutFacilitator collectionViewEditingCellsAtIndexPaths:indexPaths]; if (!self.asyncDataSource || _superIsPendingDataLoad) { return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes } if (_performingBatchUpdates) { + [_layoutFacilitator collectionViewBatchingCellEditsAtIndexPaths:indexPaths]; [_batchUpdateBlocks addObject:^{ [super insertItemsAtIndexPaths:indexPaths]; }]; } else { [UIView performWithoutAnimation:^{ + [_layoutFacilitator collectionViewEditingCellsAtIndexPaths:indexPaths]; [super insertItemsAtIndexPaths:indexPaths]; }]; } @@ -895,11 +897,13 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } if (_performingBatchUpdates) { + [_layoutFacilitator collectionViewBatchingCellEditsAtIndexPaths:indexPaths]; [_batchUpdateBlocks addObject:^{ [super deleteItemsAtIndexPaths:indexPaths]; }]; } else { [UIView performWithoutAnimation:^{ + [_layoutFacilitator collectionViewEditingCellsAtIndexPaths:indexPaths]; [super deleteItemsAtIndexPaths:indexPaths]; }]; } @@ -908,17 +912,18 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; - (void)rangeController:(ASRangeController *)rangeController didInsertSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions { ASDisplayNodeAssertMainThread(); - [_layoutFacilitator collectionViewEditingSectionsAtIndexSet:indexSet]; if (!self.asyncDataSource || _superIsPendingDataLoad) { return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes } if (_performingBatchUpdates) { + [_layoutFacilitator collectionViewBatchingSectionEditsAtIndexes:indexSet]; [_batchUpdateBlocks addObject:^{ [super insertSections:indexSet]; }]; } else { [UIView performWithoutAnimation:^{ + [_layoutFacilitator collectionViewEditingSectionsAtIndexSet:indexSet]; [super insertSections:indexSet]; }]; } @@ -927,17 +932,18 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; - (void)rangeController:(ASRangeController *)rangeController didDeleteSectionsAtIndexSet:(NSIndexSet *)indexSet withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions { ASDisplayNodeAssertMainThread(); - [_layoutFacilitator collectionViewEditingSectionsAtIndexSet:indexSet]; if (!self.asyncDataSource || _superIsPendingDataLoad) { return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes } if (_performingBatchUpdates) { + [_layoutFacilitator collectionViewBatchingSectionEditsAtIndexes:indexSet]; [_batchUpdateBlocks addObject:^{ [super deleteSections:indexSet]; }]; } else { [UIView performWithoutAnimation:^{ + [_layoutFacilitator collectionViewEditingSectionsAtIndexSet:indexSet]; [super deleteSections:indexSet]; }]; } diff --git a/AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h b/AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h index 719c98419e..9e0ff567e9 100644 --- a/AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h +++ b/AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h @@ -25,6 +25,27 @@ */ - (void)collectionViewEditingSectionsAtIndexSet:(NSIndexSet *)indexes; +/** + * Inform that the collectionView is adding some cell updates into a batch, + * and will perform these batch updates at a later point + * + * NOTE: used in combination with -collectionViewWillPerformBatchUpdates + */ +- (void)collectionViewBatchingCellEditsAtIndexPaths:(NSArray *)indexPaths; + +/** + * Inform that the collectionView is adding some section updates into a batch, + * and will perform these batch updates at a later point + * + * NOTE: used in combination with -collectionViewWillPerformBatchUpdates + */ +- (void)collectionViewBatchingSectionEditsAtIndexes:(NSIndexSet *)indexes; + +/** + * Informs the delegate that the collectionView is about to call performBatchUpdates + */ +- (void)collectionViewWillPerformBatchUpdates; + @end #endif /* ASCollectionViewLayoutFacilitatorProtocol_h */ diff --git a/AsyncDisplayKit/Details/ASCollectionInternal.h b/AsyncDisplayKit/Details/ASCollectionInternal.h index 5bf70dfd35..55e99d6a36 100644 --- a/AsyncDisplayKit/Details/ASCollectionInternal.h +++ b/AsyncDisplayKit/Details/ASCollectionInternal.h @@ -14,7 +14,7 @@ @interface ASCollectionView () - (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout layoutFacilitator:(id)layoutFacilitator ownedByNode:(BOOL)ownedByNode; -@property (nonatomic, strong, readonly) ASDataController *dataController; @property (nonatomic, weak, readwrite) ASCollectionNode *collectionNode; +@property (nonatomic, strong, readonly) ASDataController *dataController; @property (nonatomic, strong, readonly) ASRangeController *rangeController; @end From b26337c44930cd1c8166ebba4f7f005f977d60d4 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Wed, 27 Jan 2016 15:05:56 -0800 Subject: [PATCH 3/3] Levi's comments --- AsyncDisplayKit/ASCollectionView.mm | 17 ++++++------ ...SCollectionViewLayoutFacilitatorProtocol.h | 26 +++++++------------ 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index 7cae446342..e8ae908593 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -876,13 +876,13 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } if (_performingBatchUpdates) { - [_layoutFacilitator collectionViewBatchingCellEditsAtIndexPaths:indexPaths]; + [_layoutFacilitator collectionViewWillEditCellsAtIndexPaths:indexPaths batched:YES]; [_batchUpdateBlocks addObject:^{ [super insertItemsAtIndexPaths:indexPaths]; }]; } else { + [_layoutFacilitator collectionViewWillEditCellsAtIndexPaths:indexPaths batched:NO]; [UIView performWithoutAnimation:^{ - [_layoutFacilitator collectionViewEditingCellsAtIndexPaths:indexPaths]; [super insertItemsAtIndexPaths:indexPaths]; }]; } @@ -891,19 +891,18 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; - (void)rangeController:(ASRangeController *)rangeController didDeleteNodes:(NSArray *)nodes atIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions { ASDisplayNodeAssertMainThread(); - [_layoutFacilitator collectionViewEditingCellsAtIndexPaths:indexPaths]; if (!self.asyncDataSource || _superIsPendingDataLoad) { return; // if the asyncDataSource has become invalid while we are processing, ignore this request to avoid crashes } if (_performingBatchUpdates) { - [_layoutFacilitator collectionViewBatchingCellEditsAtIndexPaths:indexPaths]; + [_layoutFacilitator collectionViewWillEditCellsAtIndexPaths:indexPaths batched:YES]; [_batchUpdateBlocks addObject:^{ [super deleteItemsAtIndexPaths:indexPaths]; }]; } else { + [_layoutFacilitator collectionViewWillEditCellsAtIndexPaths:indexPaths batched:NO]; [UIView performWithoutAnimation:^{ - [_layoutFacilitator collectionViewEditingCellsAtIndexPaths:indexPaths]; [super deleteItemsAtIndexPaths:indexPaths]; }]; } @@ -917,13 +916,13 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } if (_performingBatchUpdates) { - [_layoutFacilitator collectionViewBatchingSectionEditsAtIndexes:indexSet]; + [_layoutFacilitator collectionViewWillEditSectionsAtIndexSet:indexSet batched:YES]; [_batchUpdateBlocks addObject:^{ [super insertSections:indexSet]; }]; } else { + [_layoutFacilitator collectionViewWillEditSectionsAtIndexSet:indexSet batched:NO]; [UIView performWithoutAnimation:^{ - [_layoutFacilitator collectionViewEditingSectionsAtIndexSet:indexSet]; [super insertSections:indexSet]; }]; } @@ -937,13 +936,13 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } if (_performingBatchUpdates) { - [_layoutFacilitator collectionViewBatchingSectionEditsAtIndexes:indexSet]; + [_layoutFacilitator collectionViewWillEditSectionsAtIndexSet:indexSet batched:YES]; [_batchUpdateBlocks addObject:^{ [super deleteSections:indexSet]; }]; } else { + [_layoutFacilitator collectionViewWillEditSectionsAtIndexSet:indexSet batched:NO]; [UIView performWithoutAnimation:^{ - [_layoutFacilitator collectionViewEditingSectionsAtIndexSet:indexSet]; [super deleteSections:indexSet]; }]; } diff --git a/AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h b/AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h index 9e0ff567e9..514df97448 100644 --- a/AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h +++ b/AsyncDisplayKit/ASCollectionViewLayoutFacilitatorProtocol.h @@ -17,29 +17,23 @@ /** * Inform that the collectionView is editing the cells at a list of indexPaths + * + * @param indexPaths, an array of NSIndexPath objects of cells being/will be edited. + * @param isBatched, indicates whether the editing operation will be batched by the collectionView + * + * NOTE: when isBatched, used in combination with -collectionViewWillPerformBatchUpdates */ -- (void)collectionViewEditingCellsAtIndexPaths:(NSArray *)indexPaths; +- (void)collectionViewWillEditCellsAtIndexPaths:(NSArray *)indexPaths batched:(BOOL)isBatched; /** * Inform that the collectionView is editing the sections at a set of indexes - */ -- (void)collectionViewEditingSectionsAtIndexSet:(NSIndexSet *)indexes; - -/** - * Inform that the collectionView is adding some cell updates into a batch, - * and will perform these batch updates at a later point * - * NOTE: used in combination with -collectionViewWillPerformBatchUpdates - */ -- (void)collectionViewBatchingCellEditsAtIndexPaths:(NSArray *)indexPaths; - -/** - * Inform that the collectionView is adding some section updates into a batch, - * and will perform these batch updates at a later point + * @param indexes, an NSIndexSet of section indexes being/will be edited. + * @param isBatched, indicates whether the editing operation will be batched by the collectionView * - * NOTE: used in combination with -collectionViewWillPerformBatchUpdates + * NOTE: when isBatched, used in combination with -collectionViewWillPerformBatchUpdates */ -- (void)collectionViewBatchingSectionEditsAtIndexes:(NSIndexSet *)indexes; +- (void)collectionViewWillEditSectionsAtIndexSet:(NSIndexSet *)indexes batched:(BOOL)batched; /** * Informs the delegate that the collectionView is about to call performBatchUpdates