2017-01-19 1 views
2

Как я могу загрузить больше данных во время прокрутки вверх, не теряя текущего смещения oh UITableView?UITableView загружает больше данных при прокрутке вверх?

Вот что я пытаюсь достичь:

Это целый набор данных:

строки 1
строка 2
строка 3
строка 4
строка 5
строка 6
строка 7
строка 8 *
ряд 9
строка 10
строка 11
строка 12
строка 13
строка 14
строка 15

Теперь представьте, что пользователь загружен те, выделенные полужирным шрифтом, а смещение по row 8 , если пользователь прокручивает вверх и достигает row 7, я хочу загрузить и вставить строки от 1 до 5 без перехода с row 7. Помня о том, что пользователь может прокручивать, поэтому, когда данные достигли телефона, он находится в row 6, поэтому я не могу перескочить обратно до row 7, но сохраните прокрутку гладкой и естественной (как это происходит при загрузке большего количества данных при прокрутке вниз , что данные перезагружаются без перекоса таблицы из строк).

Кстати, путем смещения я имею в виду свойство contentOffsetUITableView.

Спасибо за вашу помощь, я действительно ценю это!

ответ

2

Когда вы обновляете свои данные, вам нужно сначала получить текущее смещение tableView. Затем, вы можете добавить высоту добавленных данных в смещение и установить Tableview-х смещение примерно так:

func updateWithContentOffsset(data: [String]) { 
    guard let tableView = tableView else { 
     return 
    } 
    let currentOffset = tableView.contentOffset 
    let yOffset = CGFloat(data.count) * tableView.rowHeight // MAKE SURE YOU SET THE ROW HEIGHT OTHERWISE IT WILL BE ZERO!!! 
    let newOffset = CGPoint(x: currentOffset.x, y: currentOffset.y + yOffset) 
    tableView.reloadData() 
    tableView.setContentOffset(newOffset, animated: false) 
} 

Вы также можете посмотреть на gist, которую я создал. Просто откройте новую игровую площадку iOS и скопируйте ее.

Единственное, что вы должны знать, это убедиться, что вы знаете свою высоту строки, чтобы добавить к смещению.

+1

Спасибо! До вашего ответа я пытался вычислить смещение каждой строки, но у меня были проблемы, такие как переходы между смещением. Я думаю, что дело в том, что я пытался вычислить смещение сразу после метода 'reloadData()' (очевидно, я сохранил предыдущее смещение). –

1

Теперь представьте, что пользователь загрузил те, которые выделены жирным шрифтом, а смещение - в строке 8, если пользователь прокручивает вверх и достигает строки 7, я хочу загрузить и вставить строки от 1 до 5 без прыжка из строки 7.

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

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

  • Запрос данных на столько строк как вы разумно можете уже в разумных пределах. Количество данных, отображаемых в одной строке, обычно невелико, поэтому запрос нескольких сотен строк сразу не должен быть большим делом.

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

+0

Хотя этот первый ответ попал прямо в мою проблему, ваш просветил меня идеей, которую я буду использовать позже. Идея состоит в том, чтобы загрузить весь набор строк, которые мне понадобятся, но просто запросить данные, которые я покажу, скажем, первые 50, затем запросить следующее по необходимости и т. Д. Так же, как вы объяснили. Спасибо, Калеб! –

2

@Pratik Patel Bellow ответ лучший. Справа или вызовите функцию ниже в ответе веб-службы.

func updateWithScroll(data: [String]) { 
    guard let tableView = tableView else { 
     return 
    } 
    guard let currentVisibleIndexPaths = tableView.indexPathsForVisibleRows else { 
     return 
    } 
    var updatedVisibleIndexPaths = [IndexPath]() 
    for indexPath in currentVisibleIndexPaths { 
     let newIndexPath = IndexPath(row: indexPath.row + data.count, section: indexPath.section) 
     updatedVisibleIndexPaths.append(newIndexPath) 
    } 
    tableView.reloadData() 
    tableView.scrollToRow(at: updatedVisibleIndexPaths[0], at: .top, animated: false) 
}