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