From 71965a22429665e6fb9be1da266de2c5306c0856 Mon Sep 17 00:00:00 2001 From: Mikhail Mulyar Date: Fri, 14 Mar 2014 12:45:26 +0400 Subject: [PATCH 1/2] Fix for issue #19 --- .../Controllers/TLIndexPathController.m | 28 ++++++++++++- .../Data Model/TLIndexPathUpdates.h | 3 ++ .../Data Model/TLIndexPathUpdates.m | 39 +++++++++++++------ 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/TLIndexPathTools/Controllers/TLIndexPathController.m b/TLIndexPathTools/Controllers/TLIndexPathController.m index 466278f..b345175 100644 --- a/TLIndexPathTools/Controllers/TLIndexPathController.m +++ b/TLIndexPathTools/Controllers/TLIndexPathController.m @@ -32,6 +32,7 @@ @interface TLIndexPathController () @property (strong, nonatomic) NSFetchedResultsController *backingController; @property (strong, nonatomic) TLIndexPathDataModel *oldDataModel; +@property (strong, nonatomic) NSMutableArray *updatedObjects; @property (nonatomic) BOOL performingBatchUpdate; @property (nonatomic) BOOL pendingConvertFetchedObjectsToDataModel; @end @@ -165,8 +166,8 @@ - (void)setItems:(NSArray *)items dataModel = [[TLIndexPathDataModel alloc] initWithItems:items]; } else { dataModel = [[TLIndexPathDataModel alloc] initWithItems:items - sectionNameKeyPath:self.dataModel.sectionNameKeyPath - identifierKeyPath:self.dataModel.identifierKeyPath]; + sectionNameKeyPath:self.dataModel.sectionNameKeyPath + identifierKeyPath:self.dataModel.identifierKeyPath]; } self.dataModel = dataModel; } @@ -205,6 +206,13 @@ - (void)dequeuePendingUpdates } } TLIndexPathUpdates *updates = [[TLIndexPathUpdates alloc] initWithOldDataModel:self.oldDataModel updatedDataModel:self.dataModel]; + + if (self.updatedObjects) + { + [updates addModifiedItems:self.updatedObjects]; + self.updatedObjects = nil; + } + if ([self.delegate respondsToSelector:@selector(controller:didUpdateDataModel:)] && !self.ignoreDataModelChanges) { [self.delegate controller:self didUpdateDataModel:updates]; } @@ -288,6 +296,22 @@ - (TLIndexPathDataModel *)convertFetchedObjectsToDataModel { } #pragma mark - NSFetchedResultsControllerDelegate +- (void) controllerWillChangeContent:(NSFetchedResultsController *)controller +{ + self.updatedObjects = [NSMutableArray array]; +} + +- (void) controller:(NSFetchedResultsController *)controller + didChangeObject:(id)anObject + atIndexPath:(NSIndexPath *)indexPath + forChangeType:(NSFetchedResultsChangeType)type + newIndexPath:(NSIndexPath *)newIndexPath +{ + if (type == NSFetchedResultsChangeUpdate) + { + [self.updatedObjects addObject:anObject]; + } +} - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { diff --git a/TLIndexPathTools/Data Model/TLIndexPathUpdates.h b/TLIndexPathTools/Data Model/TLIndexPathUpdates.h index 822fc5e..62f9b43 100644 --- a/TLIndexPathTools/Data Model/TLIndexPathUpdates.h +++ b/TLIndexPathTools/Data Model/TLIndexPathUpdates.h @@ -45,4 +45,7 @@ - (void)performBatchUpdatesOnCollectionView:(UICollectionView *)collectionView; - (void)performBatchUpdatesOnCollectionView:(UICollectionView *)collectionView completion:(void(^)(BOOL finished))completion; - (id)initWithOldDataModel:(TLIndexPathDataModel *)oldDataModel updatedDataModel:(TLIndexPathDataModel *)updatedDataModel; + +- (void) addModifiedItems:(NSArray *)items; + @end diff --git a/TLIndexPathTools/Data Model/TLIndexPathUpdates.m b/TLIndexPathTools/Data Model/TLIndexPathUpdates.m index 696d0e4..34b1211 100644 --- a/TLIndexPathTools/Data Model/TLIndexPathUpdates.m +++ b/TLIndexPathTools/Data Model/TLIndexPathUpdates.m @@ -45,7 +45,7 @@ - (id)initWithOldDataModel:(TLIndexPathDataModel *)oldDataModel updatedDataModel NSMutableArray *deletedItems = [[NSMutableArray alloc] init]; NSMutableArray *movedItems = [[NSMutableArray alloc] init]; NSMutableArray *modifiedItems = [[NSMutableArray alloc] init]; - + _insertedSectionNames = insertedSectionNames; _deletedSectionNames = deletedSectionNames; _movedSectionNames = movedSectionNames; @@ -57,7 +57,7 @@ - (id)initWithOldDataModel:(TLIndexPathDataModel *)oldDataModel updatedDataModel NSOrderedSet *oldSectionNames = [NSOrderedSet orderedSetWithArray:oldDataModel.sectionNames]; NSOrderedSet *updatedSectionNames = [NSOrderedSet orderedSetWithArray:updatedDataModel.sectionNames]; - // Deleted and moved sections + // Deleted and moved sections for (NSString *sectionName in oldSectionNames) { if ([updatedSectionNames containsObject:sectionName]) { NSInteger oldSection = [oldDataModel sectionForSectionName:sectionName]; @@ -79,7 +79,7 @@ - (id)initWithOldDataModel:(TLIndexPathDataModel *)oldDataModel updatedDataModel } // Deleted and moved items - NSOrderedSet *oldItems = [NSOrderedSet orderedSetWithArray:[oldDataModel items]]; + NSOrderedSet *oldItems = [NSOrderedSet orderedSetWithArray:[oldDataModel items]]; for (id item in oldItems) { NSIndexPath *oldIndexPath = [oldDataModel indexPathForItem:item]; NSString *sectionName = [oldDataModel sectionNameForSection:oldIndexPath.section]; @@ -130,6 +130,21 @@ - (id)initWithOldDataModel:(TLIndexPathDataModel *)oldDataModel updatedDataModel return self; } +- (void) addModifiedItems:(NSArray *)items +{ + NSMutableArray *updatedItems = [NSMutableArray array]; + [updatedItems addObjectsFromArray:_modifiedItems]; + + for (id item in items) + { + if (![_modifiedItems containsObject:item] && ![_insertedItems containsObject:item] && ![_movedItems containsObject:item]) + [updatedItems addObject:item]; + } + + _modifiedItems = updatedItems; +} + + - (void)performBatchUpdatesOnTableView:(UITableView *)tableView withRowAnimation:(UITableViewRowAnimation)animation { [self performBatchUpdatesOnTableView:tableView withRowAnimation:animation completion:nil]; @@ -141,9 +156,9 @@ - (void)performBatchUpdatesOnTableView:(UITableView *)tableView withRowAnimation [tableView reloadData]; return; } - + [CATransaction begin]; - + [CATransaction setCompletionBlock: ^{ //modified items have to be reloaded after all other batch updates @@ -156,16 +171,18 @@ - (void)performBatchUpdatesOnTableView:(UITableView *)tableView withRowAnimation for (id item in self.modifiedItems) { NSIndexPath *indexPath = [self.updatedDataModel indexPathForItem:item]; [indexPaths addObject:indexPath]; - [tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation]; } - } + + [tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone]; + + } if (completion) { completion(YES); } }]; - + [tableView beginUpdates]; if (self.insertedSectionNames.count) { @@ -262,9 +279,9 @@ - (void)performBatchUpdatesOnCollectionView:(UICollectionView *)collectionView c } return; } - + [collectionView performBatchUpdates:^{ - + if (self.insertedSectionNames.count) { NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] init]; for (NSString *sectionName in self.insertedSectionNames) { @@ -318,7 +335,7 @@ - (void)performBatchUpdatesOnCollectionView:(UICollectionView *)collectionView c } // TODO update modified items - + } completion:^(BOOL finished) { if (completion) { completion(finished); From 7e3bddec9f8d69bdab227baf3f5f99f2788de1bb Mon Sep 17 00:00:00 2001 From: Mikhail Mulyar Date: Mon, 17 Mar 2014 14:14:41 +0400 Subject: [PATCH 2/2] Fix for issue #20 --- .../Data Model/TLIndexPathUpdates.m | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/TLIndexPathTools/Data Model/TLIndexPathUpdates.m b/TLIndexPathTools/Data Model/TLIndexPathUpdates.m index 34b1211..e9fcaed 100644 --- a/TLIndexPathTools/Data Model/TLIndexPathUpdates.m +++ b/TLIndexPathTools/Data Model/TLIndexPathUpdates.m @@ -85,8 +85,9 @@ - (id)initWithOldDataModel:(TLIndexPathDataModel *)oldDataModel updatedDataModel NSString *sectionName = [oldDataModel sectionNameForSection:oldIndexPath.section]; if ([updatedDataModel containsItem:item]) { NSIndexPath *updatedIndexPath = [updatedDataModel indexPathForItem:item]; - //can't rely on isEqual, so must use compare - if ([oldIndexPath compare:updatedIndexPath] != NSOrderedSame) { + NSString *updatedSectionName = [updatedDataModel sectionNameForSection:updatedIndexPath.section]; + //can't rely on isEqual, so must use compare + if ([oldIndexPath compare:updatedIndexPath] != NSOrderedSame || ![updatedSectionName isEqualToString:sectionName]) { // Don't move items in moved sections if (![movedSectionNames containsObject:sectionName]) { // TODO Not sure if this is correct when moves are combined with inserts and/or deletes @@ -94,11 +95,19 @@ - (id)initWithOldDataModel:(TLIndexPathDataModel *)oldDataModel updatedDataModel // has moved if (oldIndexPath.row == updatedIndexPath.row) { NSString *oldSectionName = [oldDataModel sectionNameForSection:oldIndexPath.section]; - NSString *updatedSectionName = [updatedDataModel sectionNameForSection:updatedIndexPath.section]; if ([oldSectionName isEqualToString:updatedSectionName]) continue; } - [movedItems addObject:item]; - } + + if (![deletedSectionNames containsObject:sectionName]) + [movedItems addObject:item]; + else + { + [deletedItems addObject:item]; + + if (![insertedSectionNames containsObject:updatedSectionName]) + [insertedItems addObject:item]; + } + } } } else { // Don't delete items in deleted sections