UITableView contentSize

Fogmeister picture Fogmeister · Nov 1, 2012 · Viewed 24.3k times · Source

Having a problem with a couple of table views in my app.

The problem happens when the contents of the table changes (and therefore the content of the tableview gets bigger).

For some reason the contentSize of the UITableView stays the same meaning I can't scroll to see the new content.

This happens either when a particular cell gets bigger (after a [tableView reloadData];) or when I add new cells (using the NSFetchedResultsController delegate methods).

Is there something I need to do for the tableView to readjust its contentSize?

Edit to show code but this is just boilerplate NSFetchedResultsController delegate code...

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:(OJFPunchListCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;

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


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];
}

I've done this kind of thing before in iOS5 and never had a problem with it. Seems this is potentially an iOS6 change?

::EDIT::

The stupid thing about this is that I have a number of other UITableViewControllers in the same app and they are all working fine. I can add new cells, add dynamically sized cells, resize cells, etc... and the tables all scroll properly all the way up and down all the content.

This problem is now happening on a couple of tableview that I've added recently.

::EDIT::

OK, just doing some debugging. When I first go into the Table View the contentSize.height is 594.

When I then add a new item and go back into the same tableviewController the contentSize.height is 749.

However, I can't scroll to see the newly added cell at the bottom of the tableView. It just wont' scroll there. It bounces at the old contentSize height.

Answer

Zoltán picture Zoltán · Jul 8, 2013

I've been running into the same problem and ended up with this workaround. I'm setting the contentSize right after [self.tableView endUpdates];

[self.tableView endUpdates];

NSLog(@"%f", self.tableView.contentSize.height);

self.tableView.contentSize = [self.tableView sizeThatFits:CGSizeMake(CGRectGetWidth(self.tableView.bounds), CGFLOAT_MAX)];

NSLog(@"%f", self.tableView.contentSize.height);

[self.tableView setContentInset:UIEdgeInsetsMake(50, 0, -50, 0)];