Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does insertRowsAtIndexPaths always cause the TableView to scroll to the top?

I've been banging my head on this problem for hours, but every time I try something like this:

    self.dataArray.append(newCellObj)

and then I do this:

    self.tableView.beginUpdates()
    self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Top)
    self.tableView.endUpdates()

The UITableView will automatically scroll to the top of the page.

Even if I try:

    self.tableView.scrollEnabled = false
    self.tableView.beginUpdates()
    self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Top)
    self.tableView.endUpdates()

The UITableView will still scroll to the top even with scrolling completely disabled. What exactly causes the ScrollView to scroll to the top after insertRowsAtIndexPaths is called?

The only solution I have for this issue is to use this:

    self.tableView.reloadData()

instead. If I use reloadData instead than it's fine, but then I lose the nice animation which I'd really like to keep.

I also have self.tableView.scrollsToTop = false and I've tried many other configurations like that that could disable scrolling somehow, but, there's something that overrides this after insertRowsAtIndexPaths

like image 770
Mateusz266 Avatar asked Feb 21 '16 22:02

Mateusz266


2 Answers

I was encountering the same issue as OP. Additionaly, sometimes some of my table view cells would go "blank" and disappear altogether, which led me to this related question.

For me, the solution was to do ONE of the following:

  • implement func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
  • disable auto layout
  • set a more accurate estimatedRowHeight on my UITableView
like image 186
Ilias Karim Avatar answered Nov 02 '22 11:11

Ilias Karim


- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
     return UITableViewAutomaticDimension;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
     return UITableViewAutomaticDimension;
}

// I'm use auto layout and this variant without animation works 
// ...insert object to datasource
NSUInteger idx = [datasource indexOfObject:myNewObject];
if ( NSNotFound != idx )
{
    NSIndexPath *path = [NSIndexPath indexPathForRow:idx inSection:0];
    [self.table beginUpdates];
    [self.table insertRowsAtIndexPaths:@[path]
                      withRowAnimation:UITableViewRowAnimationNone];
    [self.table endUpdates];
    [self.table scrollToRowAtIndexPath:path 
                      atScrollPosition:UITableViewScrollPositionBottom 
                              animated:NO];
}
like image 1
Roman Solodyashkin Avatar answered Nov 02 '22 12:11

Roman Solodyashkin