Skip to content

Instantly share code, notes, and snippets.

@bobspryn
Created April 11, 2014 22:30
Show Gist options
  • Select an option

  • Save bobspryn/10506869 to your computer and use it in GitHub Desktop.

Select an option

Save bobspryn/10506869 to your computer and use it in GitHub Desktop.
changesets.m
- (void) init {
[super init];
self.activityItemsTableChangeSignal = [[[RACSignal zip:@[[RACObserve(self, activityItems) ignore:nil],
[RACObserve(self, previousActivityItems) ignore:nil]]]
skip:1]
reduceEach:^id (NSOrderedSet *activityItems, NSOrderedSet *previousActivityItems){
return [self generateChangeSetsForSection:kTCTableUpdateSectionActivity withNewObjects:activityItems fromOldObjects:previousActivityItems];
}];
}
- (NSDictionary *) generateChangeSetsForSection:(NSString *) section withNewObjects:(NSOrderedSet *) newObjects fromOldObjects:(NSOrderedSet *) oldObjects {
NSSet *newObjectsSet = [newObjects set];
NSSet *previousObjectsSet = [oldObjects set];
NSMutableSet *insertedObjects = [newObjectsSet mutableCopy];
[insertedObjects minusSet:previousObjectsSet];
NSMutableSet *deletedObjects = [previousObjectsSet mutableCopy];
[deletedObjects minusSet:newObjectsSet];
NSMutableSet *updatedObjects = [newObjectsSet mutableCopy];
[updatedObjects minusSet:insertedObjects];
[updatedObjects minusSet:deletedObjects];
NSMutableSet *changes = [NSMutableSet set];
for (id object in insertedObjects) {
[changes addObject:@{kTCTableUpdateType: @(NSFetchedResultsChangeInsert),
kTCTableUpdateNewIndex: @([newObjects indexOfObject:object])}];
}
for (id object in deletedObjects) {
[changes addObject:@{kTCTableUpdateType: @(NSFetchedResultsChangeDelete),
kTCTableUpdateOldIndex: @([oldObjects indexOfObject:object])}];
}
for (id object in updatedObjects) {
[changes addObject:@{kTCTableUpdateType: @(NSFetchedResultsChangeMove),
kTCTableUpdateOldIndex: @([oldObjects indexOfObject:object]),
kTCTableUpdateNewIndex: @([newObjects indexOfObject:object])}];
}
return @{kTCTableUpdateSection: section,
kTCTableUpdateChanges: [changes copy]};
}
// listening to the table update signal, perform the updates
[self.viewModel.tableUpdateSignal
subscribeNext:^(RACTuple *values) {
@strongify(self);
[self.tableView beginUpdates];
for (NSDictionary *sectionChanges in values) {
NSUInteger tableSection = [sectionChanges[kTCTableUpdateSection] isEqualToString:kTCTableUpdateSectionInbox] ? TableSectionInbox: TableSectionActivity;
NSArray *changes = sectionChanges[kTCTableUpdateChanges];
BOOL deletedEmptyStateRow = NO;
BOOL insertedEmptyStateRow = NO;
NSUInteger newCount = tableSection == TableSectionInbox ? self.viewModel.inboxItems.count : self.viewModel.activityItems.count;
NSUInteger previousCount = tableSection == TableSectionInbox ? self.viewModel.previousInboxItems.count : self.viewModel.previousActivityItems.count;
for (NSDictionary *change in changes) {
if (((NSNumber *)change[kTCTableUpdateType]).integerValue == NSFetchedResultsChangeInsert ) {
if (previousCount == 0 && !deletedEmptyStateRow) {
[self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:tableSection]] withRowAnimation:UITableViewRowAnimationAutomatic];
deletedEmptyStateRow = YES;
}
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:((NSNumber *)change[kTCTableUpdateNewIndex]).integerValue inSection:tableSection]] withRowAnimation:UITableViewRowAnimationAutomatic];
} else if (((NSNumber *)change[kTCTableUpdateType]).integerValue == NSFetchedResultsChangeMove) {
[self.tableView moveRowAtIndexPath:[NSIndexPath indexPathForRow:((NSNumber *)change[kTCTableUpdateOldIndex]).integerValue inSection:tableSection]
toIndexPath:[NSIndexPath indexPathForRow:((NSNumber *)change[kTCTableUpdateNewIndex]).integerValue inSection:tableSection]];
} else {
[self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:((NSNumber *)change[kTCTableUpdateOldIndex]).integerValue inSection:tableSection]]
withRowAnimation:UITableViewRowAnimationAutomatic];
if (newCount == 0 && !insertedEmptyStateRow) {
[self.tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:tableSection]] withRowAnimation:UITableViewRowAnimationAutomatic];
insertedEmptyStateRow = YES;
}
}
}
}
[self.tableView endUpdates];
}];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment