UITableView вставляет строки без прокрутки

У меня есть список данных, которые я извлекаю из веб-службы. Я обновляю данные, и я хочу вставить данные в представление таблицы над текущими данными, но я хочу сохранить текущую позицию прокрутки в таблице.

В настоящий момент я выполняю это, вставив раздел выше моего текущего раздела, но он фактически вставляет, прокручивает вверх, а затем мне приходится вручную прокручивать вниз. Я пытался отключить прокрутку в таблице до этого, но это тоже не сработало.

Это выглядит изменчивым и кажется хриплым. Что это лучший способ сделать это?

[tableView beginUpdates];

[tableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];

[tableView endUpdates];

NSUInteger iContentOffset = 200; //height of inserted rows

[tableView setContentOffset:CGPointMake(0, iContentOffset)];

Ответ 1

Лучший способ найти мое желаемое поведение - не анимировать вставку вообще. Анимация вызывала изменчивость.

Вместо этого я звоню:

[tableView reloadData];

// set the content offset to the height of inserted rows 
// (2 rows * 44 points = 88 in this example)
[tableView setContentOffset:CGPointMake(0, 88)]; 

Это означает, что перезагрузка появляется одновременно с изменением смещения содержимого.

Ответ 2

Если я правильно понимаю вашу миссию,

Я сделал это следующим образом:

if(self.tableView.contentOffset.y > ONE_OR_X_ROWS_HEIGHT_YOUDECIDE
{

    self.delayOffset = self.tableView.contentOffset;
    self.delayOffset = CGPointMake(self.delayOffset.x, self.delayOffset.y+ insertedRowCount * ONE_ROW_HEIGHT);

    [self.tableView reloadData];

    [self.tableView setContentOffset:self.delayOffset animated:NO];    


}else
{
    [self.tableView insertRowsAtIndexPath:indexPathArray   WithRowAnimation:UITableViewRowAnimationTop];

}

С помощью этого кода, если пользователь находится в середине таблицы, а не сверху, uitableview перезагрузит новые строки без анимации и без прокрутки. Если пользователь находится в верхней части таблицы, он увидит анимацию вставки строки.

Просто обратите внимание на код, я предполагаю, что высота строки равна, если нет, просто вычислите высоту всех новых строк, которые вы собираетесь вставлять. Надеюсь, что это поможет.

Ответ 3

Для других зрителей, ищущих решение Swift 3 +:

Вам нужно сохранить текущее смещение UITableView, затем перезагрузить, а затем установить смещение на UITableView.

func reloadTableView(_ tableView: UITableView) {
    let contentOffset = tableView.contentOffset
    tableView.reloadData()
    tableView.layoutIfNeeded()
    tableView.setContentOffset(contentOffset, animated: false)
}

Вызывается: reloadTableView(self.tableView)

Ответ 4

Просто позвоните setContentOffset до endUpdates, это работает для меня.

[tableView setContentOffset:CGPointMake(0, iContentOffset)];
[tableView endUpdates];

Ответ 5

Я использую ячейки для самостоятельной калибровки, и оценка высоты строки была бесполезной, поскольку ячейки могут значительно различаться по размеру. Поэтому вычисление contentOffset не работает для меня.

Решение, с которым я закончил, было довольно простым и прекрасно работает. Поэтому сначала я должен упомянуть, что у меня есть вспомогательные методы, которые позволяют мне получить элемент данных для указательного пути, а наоборот - путь индекса для элемента данных.

-(void) loadMoreElements:(UIRefreshControl *) refreshControl {
  NSIndexPath *topIndexPath = [NSIndexPath indexPathForRow:0 inSection:0]
  id topElement = [myModel elementAtIndexPath:topIndexPath];

  // Somewhere here you'll need to tell your model to get more data
  [self.tableView reloadData];

  NSIndexPath *indexPath = [myModel indexPathForElement:topElement];

  [self.tableView scrollToRowAtIndexPath:indexPath 
                        atScrollPosition:UITableViewScrollPositionTop 
                                animated:NO];

  [refreshControl endRefreshing];
}