_ASHierarchyChangeSet: add section change mapping methods, fix section exclusions

This commit is contained in:
Adlai Holler 2015-11-26 10:42:35 -08:00
parent 4bfdd82568
commit 41ecaa7bb2
2 changed files with 50 additions and 8 deletions

View File

@ -34,6 +34,21 @@ typedef NS_ENUM(NSInteger, _ASHierarchyChangeType) {
@interface _ASHierarchyChangeSet : NSObject
/// @precondition The change set must be completed.
@property (nonatomic, strong, readonly) NSIndexSet *deletedSections;
/// @precondition The change set must be completed.
@property (nonatomic, strong, readonly) NSIndexSet *insertedSections;
/// @precondition The change set must be completed.
@property (nonatomic, strong, readonly) NSIndexSet *reloadedSections;
/**
Get the section index after the update for the given section before the update.
@precondition The change set must be completed.
@returns The new section index, or NSNotFound if the given section was deleted.
*/
- (NSInteger)newSectionForOldSection:(NSInteger)oldSection;
@property (nonatomic, readonly) BOOL completed;
/// Call this once the change set has been constructed to prevent future modifications to the changeset. Calling this more than once is a programmer error.

View File

@ -99,6 +99,17 @@
}
}
- (NSInteger)newSectionForOldSection:(NSInteger)oldSection
{
[self _ensureCompleted];
if ([_deletedSections containsIndex:oldSection]) {
return NSNotFound;
}
NSInteger indexAfterDeletes = oldSection - [_deletedSections countOfIndexesInRange:NSMakeRange(0, oldSection)];
return indexAfterDeletes + [_insertedSections countOfIndexesInRange:NSMakeRange(0, indexAfterDeletes)];
}
- (void)deleteItems:(NSArray *)indexPaths animationOptions:(ASDataControllerAnimationOptions)options
{
[self _ensureNotCompleted];
@ -162,15 +173,31 @@
[_ASHierarchySectionChange sortAndCoalesceChanges:_insertSectionChanges];
[_ASHierarchySectionChange sortAndCoalesceChanges:_reloadSectionChanges];
// Item deletes in deleted sections need not be reported.
NSIndexSet *deletedSections = [_ASHierarchySectionChange allIndexesInChanges:_deleteSectionChanges];
[_ASHierarchyItemChange sortAndCoalesceChanges:_deleteItemChanges ignoringChangesInSections:deletedSections];
_deletedSections = [[_ASHierarchySectionChange allIndexesInChanges:_deleteSectionChanges] copy];
_insertedSections = [[_ASHierarchySectionChange allIndexesInChanges:_insertSectionChanges] copy];
_reloadedSections = [[_ASHierarchySectionChange allIndexesInChanges:_reloadSectionChanges] copy];
// Item reloads/inserts in reloaded/inserted sections need not be reported.
NSMutableIndexSet *reloadedAndInsertedSections = [_ASHierarchySectionChange allIndexesInChanges:_reloadSectionChanges];
[reloadedAndInsertedSections addIndexes:[_ASHierarchySectionChange allIndexesInChanges:_insertSectionChanges]];
[_ASHierarchyItemChange sortAndCoalesceChanges:_reloadItemChanges ignoringChangesInSections:reloadedAndInsertedSections];
[_ASHierarchyItemChange sortAndCoalesceChanges:_insertItemChanges ignoringChangesInSections:reloadedAndInsertedSections];
// These are invalid old section indexes.
NSMutableIndexSet *deletedOrReloaded = [_deletedSections mutableCopy];
[deletedOrReloaded addIndexes:_reloadedSections];
// These are invalid new section indexes.
NSMutableIndexSet *insertedOrReloaded = [_insertedSections mutableCopy];
// Get the new section that each reloaded section index corresponds to.
[_reloadedSections enumerateIndexesUsingBlock:^(NSUInteger oldIndex, __unused BOOL * stop) {
NSUInteger newIndex = [self newSectionForOldSection:oldIndex];
if (newIndex != NSNotFound) {
[insertedOrReloaded addIndex:newIndex];
}
}];
// Ignore item reloads/deletes in reloaded/deleted sections.
[_ASHierarchyItemChange sortAndCoalesceChanges:_deleteItemChanges ignoringChangesInSections:deletedOrReloaded];
[_ASHierarchyItemChange sortAndCoalesceChanges:_reloadItemChanges ignoringChangesInSections:deletedOrReloaded];
// Ignore item inserts in reloaded(new)/inserted sections.
[_ASHierarchyItemChange sortAndCoalesceChanges:_insertItemChanges ignoringChangesInSections:insertedOrReloaded];
}
}