Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to scroll tableview after inserting a row at the bottom correctly?

Here is the code I use:

//inserting a row at the bottom first
_numberOfRecords++;
[_tableView beginUpdates];
[_tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:_numberOfRecords-1 inSection:0]] withRowAnimation:UITableViewRowAnimationBottom];
[_tableView endUpdates];
//clear text
_inputField.text = @"";

//then scroll to bottom
CGPoint bottomOffset = CGPointMake(0, _tableView.contentSize.height + 44.0 + _tableView.contentInset.top - _tableView.bounds.size.height);
NSLog(@"%f", _tableView.contentSize.height + 44.0 + _tableView.contentInset.top - _tableView.bounds.size.height);
[_tableView setContentOffset:bottomOffset animated:YES];

This would scroll the tableview in a very strange way. But if I put the scrolling code BEFORE the insertion, it works fine except that it ignores the latest inserted row. That is, it scrolls to the second last row instead of scrolling to the very last row (of course, because it scrolls before inserting a new roll.)

So I believe this code has no problem of the position where it should scroll to. The problem probably comes from row insertion to tableview. It violates the animation of scrolling the table view.

I am doing this to make a chatting view. Each time the user sends or receives a message, I insert a row containing the message to a table view, and scrolls it to the bottom. That's why I use tableView here. I tried to use scrollView with label, it works fine, but tableView seems more popular in a chatting view.

I was thinking to use scrollView or tableView, and I found the built-in message app of Apple is using a tableView, so I adopt tableView. Let me know if a scrollView with Label is better than a tableView.

Anyway, how can I scroll a tableView to the bottom after inserting a new row?

like image 333
Kyle Xie Avatar asked Jan 11 '23 22:01

Kyle Xie


2 Answers

Try using UITableView's scrollToRowAtIndexPath::

[self.tableView scrollToRowAtIndexPath: atScrollPosition: animated:];
like image 182
Dylan Avatar answered Jan 31 '23 17:01

Dylan


This is my own solution:

[_tableView reloadData];

    //scroll to bottom
double y = _tableView.contentSize.height - _tableView.bounds.size.height;
CGPoint bottomOffset = CGPointMake(0, y);
NSLog(@"after = %f", y);
if (y > -_tableView.contentInset.top)
    [_tableView setContentOffset:bottomOffset animated:YES];

Firstly reloadData after endUpdates. This ensures the tableView contentSize is updated after inserting a new row. Then check if the scrolling distance is greater than the contentInset.top (this is for avoiding the tableview hiding behind the status bar and navigation bar) then to scroll down, otherwise not to scroll because of some weird animation.

Alternatively, you can simply use

[self.tableView scrollToRowAtIndexPath: inSection: atScrollPosition: animated:];

to scroll to the row you want. But this doesn't handle cells with sections and footers very well. For plain tableViewCell, you can just use this to do the magic. Otherwise you may find my trick solution performs better.

Anyway, thanks for all your answers.

like image 32
Kyle Xie Avatar answered Jan 31 '23 15:01

Kyle Xie