Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView contentSize

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.

like image 326
Fogmeister Avatar asked Nov 01 '12 16:11

Fogmeister


2 Answers

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)];
like image 153
Zoltán Avatar answered Sep 22 '22 06:09

Zoltán


I had the same problem using a custom view controller with two child VC's, one being a tableview + fetched results controller.

I would get to the point after adding content from one vc and going back to my table that I wouldn't be able to scroll to new content at bottom.

So in my tableview + fetched results controller I adjust the content size based off of the number of fetched objects I have, regardless of where they came from.

Worst case scenario is that I didn't add any content when showing the VC, but the cost is minimal.

//In my tableview + fetched results controller class
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];


    NSUInteger objCount = self.fetchedResultsController.fetchedObjects.count;
    //My custom cell has a height of 50.0f, yours may not!
    CGFloat tableHeight = objCount * 50.0f;

    NSLog(@"%i objects, total height: %f",objCount,tableHeight);

    [self.tableView setContentSize:CGSizeMake(self.tableView.contentSize.width, tableHeight)];

}
like image 36
shazgoose Avatar answered Sep 20 '22 06:09

shazgoose