I have been working on a chat client recently. And as expected, I need to have dynamic height for the cells. I used autolayouts for that and set two important properties on UITableView
self.tableview.estimatedRowHeight = 77.5f;
self.tableview.rowHeight = UITableViewAutomaticDimension;
I also am using an inputAccessoryView
for tableView to have an ever present UITextView at the bottom just like Messages app on the iPhone. contentInset
for the tableView is set appropriately when keyboard appears and seems to work pretty good.
The problem starts when I try to scroll the tableView
to the bottom when
a) the chat is loaded for first time
b) when some new message is received.
For a) I've tried various techniques like first in viewDidLoad
, viewDidAppear
, viewWillAppear
etc even the delayed scroll using dispatch_after
or performSelector:withObject:afterDelay
both animated and non-animated. But they only work in iOS 9 not on iOS 8.
For b) I add the new chat messages to backing datastore, call reloadData
and scrolling immediately after to the last row. It works on iOS 9 but not on iOS 8. I also tried insertRowsAtIndexPaths
to insert just one new row. However, it generates an empty space between newly added row and bottom layout (which is inputAccessoryView with or without keyboard).
On iOS 8, half of the row is still invisible or sometimes multiple rows. They adjust as soon as I start to scroll.
I think the tableView
might be incorrectly estimating row height when scrolling. However, the actual row heights are as expected. No text is stripped at all.
The ViewController itself is a UIViewController
, but I have created a UITableViewController
instance for adding the UIRefreshcontrol
as described here.
Apparently, whenever I call 'reloadData' on tableView
, it just won't go to the last row properly unless I scroll Once.
updated
Apparently, I must implement tableView:heightForRowAtIndexPath:
on iOS 8 and manually determine height for each cell. Only then scrolling works properly.