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];
}