Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate data refresh (soft delete) on Core Data / UITableView

I have a table view that's backed by a fetchedResultsController. On my table cells I have a button that performs a soft delete, as far as the view is concerned... tap the button, the selector that performs the soft delete is called, and ... something is supposed to happen (I've tried a lot of things), but nothing I've tried animates like Apple's row animations.

I can perform simple row animations, like making it slide out of the way (which leaves a blank row until I tell the table to reload, which in turn is a bit of a jarring effect). This is the closest I've come:

 -(void) completeTask: (id) sender {
     NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)[[sender superview] superview]];

     NSDate *date = [[NSDate alloc] init];
     NSManagedObject *task = [self.fetchedResultsController objectAtIndexPath:indexPath];

     [task setValue:date forKey:@"complete"];

     AppController *ac = [AppController sharedAppController];
     NSManagedObjectContext *moc = [ac managedObjectContext];

     NSError *error = nil;
     if(![moc save:&error]){
         NSLog(@"%@ %@",error, [error description]);
         exit(-1);
     } else {
         UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

         CGRect cellFrame = cell.frame;
         [UIView beginAnimations:nil context:nil];
         [UIView setAnimationDuration:0.35];
         [UIView setAnimationDelegate:self];
         [UIView setAnimationDidStopSelector:@selector(someAnimationDidStop:finished:context:)];
         cell.frame = CGRectMake(cellFrame.size.width , cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height);
         [UIView commitAnimations];
     }
 }

-(void) someAnimationDidStop:(NSString *)animationID 
                    finished:(BOOL)finished context:(void *)duration {
    NSLog(@"Animation Stopped");
    [self fetchResults]; // this guy performs a new fetch and table data reload
}

I feel like I'm sort of on the right track, however I don't think this is really quite the answer. I was hoping that somehow controller:didChangeObject:atIndexPath:forChangeType:newIndexPath: would be the answer. My guess is that if I want the stock Apple animations, I will have to create a separate NSMutableArray to track the results and just make sure it's kept in sync.

Thoughts and opinions?

Thanks!!!

like image 247
Cameron Avatar asked Aug 31 '26 19:08

Cameron


1 Answers

I guess you have already a predicate for the NSFetchedResultsController that doesn't fetch those "soft deleted" objects.

So in theory all you have to do is to implement all of the NSFetchResultsControllerDelegate methods. The sample implementation from the documentation will work fine.
Don't forget to set the delegate of the NSFetchedResultsController

Then instead of manually managing cells, just change the "soft delete" value from the object. The NSFetchResultsController will monitor the context, it figures out that this change make the object disappear from the collection so it will remove the cell from the tableView.

like image 197
Matthias Bauch Avatar answered Sep 03 '26 22:09

Matthias Bauch