Repopulate supplementary views on item-level changes

Currently within `ASCollectionView`, there is an assumption that there will always be a static number of supplementary views per section—even when additional items are added or removed from that section. This is evidenced by the fact that when you invoke -[ASCollectionView insertItemsAtIndexPaths:], the data source method -[ASCollectionDataSource collectionView:nodeForSupplementaryElementOfKind:atIndexPath:] is not invoked, preventing consumers from specifying a new number of supplementary nodes for the new set of items.

With this change, the set of supplementary nodes for a section is now recalculated not only on section-level mutations, but also on item-level mutations as well. This adds item-level counterparts to the section-level `-prepareFor...` subclassing hooks in `ASDataController+Subclasses.h` to make this possible.

This should fix #1278 and #1322

This has been tested in my project and seen to fix the assertion. Open to suggestions on how to test in a more universal way.
This commit is contained in:
Eric Horacek
2016-05-05 16:23:22 -07:00
parent 3725e53fe9
commit fc5eef3269
5 changed files with 208 additions and 18 deletions

View File

@@ -772,6 +772,36 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)prepareForInsertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)willInsertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)prepareForDeleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)willDeleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)prepareForReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
- (void)willReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths
{
// Optional template hook for subclasses (See ASDataController+Subclasses.h)
}
#pragma mark - Row Editing (External API)
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withAnimationOptions:(ASDataControllerAnimationOptions)animationOptions
@@ -799,7 +829,11 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
environmentTraitCollection:environmentTraitCollection]];
}
[self prepareForInsertRowsAtIndexPaths:indexPaths];
[_editingTransactionQueue addOperationWithBlock:^{
[self willInsertRowsAtIndexPaths:indexPaths];
LOG(@"Edit Transaction - insertRows: %@", indexPaths);
[self _batchLayoutNodesFromContexts:contexts withAnimationOptions:animationOptions];
}];
@@ -819,7 +853,11 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
// FIXME: Shouldn't deletes be sorted in descending order?
NSArray *sortedIndexPaths = [indexPaths sortedArrayUsingSelector:@selector(compare:)];
[self prepareForDeleteRowsAtIndexPaths:sortedIndexPaths];
[_editingTransactionQueue addOperationWithBlock:^{
[self willDeleteRowsAtIndexPaths:sortedIndexPaths];
LOG(@"Edit Transaction - deleteRows: %@", indexPaths);
[self _deleteNodesAtIndexPaths:sortedIndexPaths withAnimationOptions:animationOptions];
}];
@@ -853,8 +891,12 @@ static void *kASSizingQueueContext = &kASSizingQueueContext;
constrainedSize:constrainedSize
environmentTraitCollection:environmentTraitCollection]];
}
[self prepareForReloadRowsAtIndexPaths:indexPaths];
[_editingTransactionQueue addOperationWithBlock:^{
[self willReloadRowsAtIndexPaths:indexPaths];
LOG(@"Edit Transaction - reloadRows: %@", indexPaths);
[self _deleteNodesAtIndexPaths:sortedIndexPaths withAnimationOptions:animationOptions];
[self _batchLayoutNodesFromContexts:contexts withAnimationOptions:animationOptions];