iOS 8 Auto cell height - Can't scroll to last row
Update: Jun 24, 2015
Apple has addressed most of these bugs as of the iOS 9.0 SDK. All of the issues are fixed as of iOS 9 beta 2, including scrolling to the top & bottom of the table view without animation, and calling reloadData
while scrolled in the middle of the table view.
Here are the remaining issues that have not been fixed yet:
- When using a large estimated row height, scrolling to the last row with animation causes the table view cells to disappear.
- When using a small estimated row height, scrolling to the last row with animation causes the table view to finish scrolling too early, leaving some cells below the visible area (and the last row still offscreen).
A new bug report (rdar://21539211) has been filed for these issues relating to scrolling with animation.
Original Answer
This is an Apple bug with the table view row height estimation, and it has existed since this functionality first was introduced in iOS 7. I have worked directly with Apple UIKit engineers and developer evangelists on this issue -- they have acknowledged that it is a bug, but do not have any reliable workaround (short of disabling row height estimation), and did not seem particularly interested in fixing it.
Note that the bug manifests itself in other ways, such as disappearing table view cells when you call reloadData
while scrolled partially or fully down (e.g. contentOffset.y
is significantly greater than 0).
Clearly, with iOS 8 self sizing cells, row height estimation is critically important, so Apple really needs to address this ASAP.
I filed this issue back on Oct 21 2013 as Radar #15283329. Please do file duplicate bug reports so that Apple prioritizes a fix.
You can attach this simple sample project to demonstrate the issue. It is based directly on Apple's own sample code.
iOS - UITableView Does Not Scroll To Last Row In Data Source
I've determined that this issue has to do with cell height. By increasing tableView.estimatedRowHeight
to 44.0, the table view scrolls flawlessly to the bottom. However, there remains an issue with when messages wrap beyond 1 line in a given cell. For each message longer than 1 line, the table scroll comes up a few more pixels short. Removing tableView.estimatedRowHeight
altogether seems to result in similar behavior as setting it to say, 44.0. I want to say my original question is answered, but I'm still not sure how to make it scroll perfectly given the likelihood of multi-line cells.
EDIT - SOLUTION
The problem of incorrect scrolling is in fact solved by removing UITableViewAutomaticDimension
and manually calculating the height in heightForRowAtIndexPath
.
scrollToRowAtIndexPath doesn't handle the last row properly
Okay, I've successfully been able to fix this issue.
The clue was in this comment by Matt Di Pasquale on a semi-related question.
It turns out that in iOS 7, the views are yet to be laid out when viewWillAppear:
is called, meaning the frame and bounds of the table view are not guaranteed to be accurate. Since the call to scrollToRowAtIndexPath:animated
must use at least one of these to calculate the offset, this makes sense as to why in my case it wasn't being handled properly.
I think in most cases people won't encounter this issue as their presenting view controller will likely have the same bounds as the presented view controller. But in my case, I was presenting a view controller that had a visible navigation bar and status bar from one that didn't have either, ergo there was an extra 64pts to account for. As can be seen in this console output:
2014-03-15 19:14:32.129 Capture[3375:60b] viewWillAppear, tv bounds: {{0, 0}, {320, 568}}
2014-03-15 19:14:32.131 Capture[3375:60b] viewDidLayoutSubviews, tv bounds: {{0, -64}, {320, 568}}
To get around the issue, I now set a flag in viewWillAppear:
that signifies there's a pending scroll and then in viewDidLayoutSubviews
, if the flag is set, I call scrollToRowAtIndexPath:animated
and unset the flag (since this method is called numerous times). This works flawlessly.
Hopefully this will help anyone else coming across the issue.
Scrolling to last row of table view only scrolls half way
This solution may be helpful of others with same issue.
This issue is a bug, see discussion here.
I use a footer view for adding comments to a feed so i used its height here and the tableview will scroll to the last row directly above the footer view:
self.tableView.reloadData();
// load the last row
let offset = CGPoint(x: 0, y: self.tableView.contentSize.height - self.tableView.frame.size.height + self.FOOTERHEIGHT);
self.tableView.contentOffset = offset;
UITableView dynamic cell heights only correct after some scrolling
I don't know this is clearly documented or not, but adding [cell layoutIfNeeded]
before returning cell solves your problem.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"TestCell"];
NSUInteger n1 = firstLabelWordCount[indexPath.row];
NSUInteger n2 = secondLabelWordCount[indexPath.row];
[cell setNumberOfWordsForFirstLabel:n1 secondLabel:n2];
[cell layoutIfNeeded]; // <- added
return cell;
}
UITableview not visible the last cell when scroll down
Use -
tableView.contentInset = UIEdgeInsetsMake(0, 0, 120, 0); //values
passed are - top, left, bottom, right
Pass bottom offset as per your needs.
Related Topics
Swift Doesn't Convert Objective-C Nserror** to Throws
Creating Custom Info Window in Swift with the Google Maps iOS Sdk
Instead of Push Segue How to Replace View Controller (Or Remove from Navigation Stack)
Implement Pushkit and Test in Development Behavior
Xcode 8 Build Crash on iOS 9.2 and Below
Force Landscape Mode in One Viewcontroller Using Swift
Install Simulator Sdk 4.3 to Xcode 4.4 on Mountain Lion
"Untrusted App Developer" Message When Installing Enterprise iOS Application
Storing Images Locally on an iOS Device
Date to Milliseconds and Back to Date in Swift
Identify New iPhone Model on Xcode (5, 5C, 5S)
Firebase Cloud Messaging - Check Existing or Available Topics
How to Reload Tableview from Another View Controller in Swift
Saving Email/Password to Keychain in iOS