2014-08-31 5 views
9

У меня есть _TableView с элементами, и я хочу установить автоматическое обновление, и я не хочу, чтобы он прокручивался при обновлении, скажем, что пользователь прокрутил 2 страницы вниз, а обновление - трижды -> так что я хотите поместить обновленный контент в верхней части таблицы без interupting пользователя прокруткеUITableView Обновить без прокрутки

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

Что было бы лучшим подходом к его достижению?

+0

надеюсь, что эти ответы помогут вам: http://stackoverflow.com/questions/5872759/uitableview-insert-rows-without-scrolling/11585557#11585557 – stosha

ответ

9

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

// dataArray is your data Source object 
    [dataArray insertObject:name atIndex:0]; 
    CGPoint contentOffset = self.tableView.contentOffset; 
    contentOffset.y += [self tableView:self.tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
    [self.tableView reloadData]; 
    [self.tableView setContentOffset:contentOffset]; 

Но для этой работы вам необходимо иметь определенный - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath метод. Или же вы можете напрямую указать высоту строки tableview, если она постоянна.

+0

Это не является постоянным, и спасибо за ваш ответ я попробуем это, – ColdSteel

+0

Да, конечно, вы определили метод '- (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath'. Примите мой ответ, если он вам поможет. – user1190882

2

Я делаю это так:

messages.insertContentsOf(incomingMsgs.reverse(), at: 0) 
table.reloadData() 

// This is for the first load, first 20 messages, scroll to bottom 
if (messages.count <= 20) { 
     let indexToScroll = NSIndexPath(forRow: saferSelf.messages.count - 1, inSection: 0) 
     table.scrollToRowAtIndexPath(indexToScroll, atScrollPosition: .Top , animated: false) 
} 
// This is to reload older messages on top of tableview 
else { 
     let indexToScroll = NSIndexPath(forRow: incomingMsgs.count, inSection: 0) 
     table.scrollToRowAtIndexPath(indexToScroll, atScrollPosition: .Top , animated: false) 
     // Remove the refreshControl.height + tableHeader.height from the offset so the content remain where it was before reload 
     let theRightOffset = CGPointMake(0, table.contentOffset.y - refreshControl.frame.height - table.headeView.frame.height) 
     table.setContentOffset(theRightOffset, animated: false) 
} 

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

var heightAtIndexPath = [NSIndexPath: CGFloat]() 
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 
    return heightAtIndexPath[indexPath] ?? UITableViewAutomaticDimension 
} 
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    heightAtIndexPath[indexPath] = cell.frame.height 
} 
12

Это ошибка iOS8 при использовании UITableViewAutomatic Dimension. Нам нужно сохранить смещение содержимого таблицы, перезагрузить таблицу, форматировать макет и установить contenOffset обратно.

CGPoint contentOffset = self.tableView.contentOffset; 
[self.tableView reloadData]; 
[self.tableView layoutIfNeeded]; 
[self.tableView setContentOffset:contentOffset]; 
+0

Эта первая строка о iOS 8 сохранила мой день. – CRDave

16

Для Swift 3+:

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

Я создал эту функцию для этой цели:

func reload(tableView: UITableView) { 

    let contentOffset = tableView.contentOffset 
    tableView.reloadData() 
    tableView.layoutIfNeeded() 
    tableView.setContentOffset(contentOffset, animated: false) 

} 

Просто назвать его: reload(tableView: self.tableView)

+0

Что делать, если табличное представление не меняет смещение, все еще загружает новые ячейки? –

+0

@RockBalbao - Я не понимаю ваш вопрос bro –

+0

Я использую NSFetchedResultsControllerDelegate. Теперь я использую UIRefreshControl для загрузки старых ячеек в scrollDown. На performFetch данные загружаются, мне нужно только перезагрузить данные. но я не хочу показывать перезагруженные ячейки. Пусть они загружаются выше. Когда я прокручиваю вверх, тогда они становятся видимыми. Поэтому для реализации этого я попытался использовать этот метод contentOffset. но до reloadData и после reloadData contentOffset одинаково, хотя он добавил несколько строк выше –

0

пытаются заменить

reloadData с

tableView.reloadRows (at: tableView!.indexPathsForVisibleRows!, with: .none),

, но вы должны заботиться о no cells, если no cells, этот метод должен вызвать сбой.

0

Если вы хотите, чтобы перезагрузить вы должны

self.tableView.reloadData()

self.tableView.layoutIfNeeded()

, а также использовать эту UITableViewDelegate

Func Tableview (_ Tableview: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { возвращение 'высоты вашей максимальной ячейки' }

и ваш Tableview будет оставаться в предыдущей позиции прокрутки без прокрутки

0

Этот код предотвратит ненужную анимацию и поддержит смещение содержимого прокрутки, это сработало для меня.

let lastScrollOffset = tableView.contentOffset 
tableView.beginUpdates() 
tableView.reloadData() 
tableView.endUpdates() 
tableView.layer.removeAllAnimations() 
tableView.setContentOffset(lastScrollOffset, animated: false) 
Смежные вопросы