Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView section footer view position after endUpdates

On ios8 I'm using core data table view controller, and after deleting rows my section footer view suddenly goes all the way down to the bottom of the UITableView. When I scroll the table view, footer view goes back to its place. How can fix this and why is this happening?

Here is the code just in case.

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{       
    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
    {
        switch(type)
        {
            case NSFetchedResultsChangeInsert:
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeDelete:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
                break;

            case NSFetchedResultsChangeUpdate:
                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeMove:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    if (self.beganUpdates)
    {
       [self.tableView endUpdates];
    }
}
like image 621
t0a0 Avatar asked Oct 07 '14 16:10

t0a0


3 Answers

This is an iOS 8 animation change. You must change your tableview style to 'grouped' in order to keep the section footer from moving to the bootom of the uitableview

like image 83
Blake Carrier Avatar answered Oct 14 '22 19:10

Blake Carrier


I just came across the same problem. When I use insertRowsAtIndexPaths.. the footer goes to the bottom. Also noticed that if you call reloadData on the table view it will fix the problem so I did this:

[CATransaction begin];
[CATransaction setCompletionBlock: ^{
    // Code to be executed upon completion
    [tableView reloadData];
}];

[tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationLeft];
[CATransaction commit]; 

All it does is reload the table when the insert animation finishes... It's not a real solution, more like avoiding the problem but it hides the issue until someone explains why does it happen and how to fix it....

like image 45
nihilvex Avatar answered Oct 14 '22 19:10

nihilvex


I ran into the same problem and spent a lot of effort to attempt to address it. And now, finally!

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {

        NATask *task = sections[indexPath.section][indexPath.row];
        [sections[indexPath.section] removeObjectAtIndex:indexPath.row];
        [appDelegate.managedObjectContext deleteObject:task];

        [CATransaction begin];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

        UIView *footerView = [tableView footerViewForSection:indexPath.section];
        CABasicAnimation *animation = [[footerView.layer animationForKey:@"position"] mutableCopy];
        CGPoint fromValue = [(NSValue *)animation.fromValue CGPointValue];
        animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, fromValue.y - 44)];
        [footerView.layer removeAnimationForKey:@"position"];
        [footerView.layer addAnimation:animation forKey:@"position"];
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, .4 * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [tableView reloadData];
        });

        [CATransaction commit];
    }
}

Of course, this is not most ideal solution, but it works! I'm almost two weeks wrestled with this problem, I hope, at least, is useful to someone.

like image 1
RoLife Avatar answered Oct 14 '22 20:10

RoLife