Reputation: 77641
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.
Upvotes: 17
Views: 24571
Reputation: 45
I have dynamic tableView with 'UITableViewAutomaticDimension'. Something happens and after reload and it's content size is equal to its frame size. After i manualy put content size to be as table bounds size, everything works. I hope this helps.
table.beginUpdates()
table.contentSize = CGSize(width: table.bounds.width, height: table.bounds.height)
table.endUpdates()
And this is after I done table.reloadData()
Upvotes: 0
Reputation: 67
Try this:
I've met with simular issue.In my situation,I drag a tableview to a custom view controller,which is presented by a push segue.If the amount of data showed in tableview exceeds some number,then I can't touch the cell on bottom of the tableview.
Many ways have been tried:set the frame/content size of the table view,and none works for me.Finally,I find the root cause and solve it in a simple way(although not gracefully).
First,the root cause:the table view created by IB has a width larger then the its parent view controller.Thus,any cell out of view's bound will not be touched.
So,the solution is simple:Go to StoryBoard,adjust the width of table view,making it smaller than the width of parent view.It seems that if one table view is created by StoryBoard,you can't change its frame by code.That's what I've found up to now. I guess it's a bug of StoryBoard.
Hope it be useful for you.
Upvotes: -2
Reputation: 1450
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)];
Upvotes: 20
Reputation: 49
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)];
}
Upvotes: 1