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

@@ -53,6 +53,23 @@ static void ASRecursivelyFindIndexPathsForMultidimensionalArray(NSObject *obj, N
}
}
static BOOL ASElementExistsAtIndexPath(NSMutableArray *mutableArray, NSIndexPath *indexPath) {
NSUInteger indexLength = indexPath.length;
ASDisplayNodeCAssert(indexLength != 0, @"Must have a non-zero indexPath length");
NSUInteger firstIndex = [indexPath indexAtPosition:0];
BOOL elementExists = firstIndex < mutableArray.count;
if (indexLength == 1) {
return elementExists;
}
if (!elementExists) {
return NO;
}
return ASElementExistsAtIndexPath(mutableArray[firstIndex], [indexPath indexPathByRemovingLastIndex]);
}
#pragma mark - Public Methods
NSObject<NSCopying> *ASMultidimensionalArrayDeepMutableCopy(NSObject<NSCopying> *obj)
@@ -142,6 +159,18 @@ NSArray *ASIndexPathsForMultidimensionalArrayAtIndexSet(NSArray *multidimensiona
return res;
}
NSArray<NSIndexPath *> *ASIndexPathsInMultidimensionalArrayIntersectingIndexPaths(NSArray *multidimensionalArray, NSArray<NSIndexPath *> *indexPaths)
{
NSMutableArray *res = [NSMutableArray array];
for (NSIndexPath *indexPath in indexPaths) {
if (ASElementExistsAtIndexPath(multidimensionalArray, indexPath)) {
[res addObject:indexPath];
}
}
return res;
}
NSArray *ASIndexPathsForTwoDimensionalArray(NSArray <NSArray *>* twoDimensionalArray)
{
NSMutableArray *result = [NSMutableArray array];