У меня есть данные tableView и json. Я хочу, чтобы tableview загружал половину данных json. Когда прокрутка табличного представления подойдет к концу первой половины, будет загружена другая половина. Кто-нибудь знает, как я могу?
Я получаю данные json из url, все данные json в начале.
Я считаю, что вам придется выполнить некоторую pagination
обработку на вашей стороне с помощью scrollViewDidScroll
, чтобы наблюдать, когда вы достигнете конца таблицы, чтобы загрузить следующую партию.
Начните с установки некоторых начальных переменных, которые помогут вам отслеживать процесс подкачки.
var pageStart = 0
var pageSize = 15
// scrollViewDidScroll will be called several times
// so we need to be able to block the loading process
var isLoadingItems = false
// Array of 50 values which you get from the API
// For example your JSON data
var totalNumberOfItems = (0...49).reduce([Int]())
{ (result, number) in
var array = result
array.append(number)
return array
}
// This will periodically be filled with items from totalNumberOfItems
var itemsToLoad: [Int] = []
Я создаю эту функцию загрузки, которая помогает добавлять элементы партиями и соответствующим образом перезагружать табличное представление.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
loadItems()
}
private func loadItems(withDelay delay: Double = 0) {
// Check that there are items to load
if pageStart < totalNumberOfItems.count, !isLoadingItems {
isLoadingItems = true
// The delay and dispatch queue is just to show you the
// loading of data in batches, it is not needed for the
// solution
if delay > 0 {
presentLoader()
}
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
if delay > 0 {
// dismiss the loader
self.dismiss(animated: true, completion: nil)
}
// Calculate the page end based on the page size or on
// the number of items remaining to load if the page size
// is greater than the number of items remaining
var pageEnd = self.pageStart + self.pageSize - 1
if pageEnd > self.totalNumberOfItems.count {
let remainingItems = self.totalNumberOfItems.count - self.pageStart - 1
pageEnd = self.pageStart + remainingItems
}
let newItems = Array(self.totalNumberOfItems[self.pageStart ... pageEnd])
self.itemsToLoad.append(contentsOf: newItems)
self.pageStart = pageEnd + 1
let indexPaths = newItems.map { IndexPath(row: $0,
section: 0) }
// Update the table view
self.tableView.beginUpdates()
self.tableView.insertRows(at: indexPaths, with: .fade)
self.tableView.endUpdates()
// scroll to first newly inserted row
if let firstNewRow = indexPaths.first {
self.tableView.scrollToRow(at: firstNewRow,
at: .top,
animated: true)
}
// Unlock the loading process
self.isLoadingItems = false
}
}
}
Затем посмотрите, достигли ли вы конца, используя scrollViewDidScroll
, и перезагрузите представление таблицы, чтобы показать вставленные строки.
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Check that the current scroll offset is > 0 so you don't get
// any false positives when the table view is set up
// and check if the current offset has reached the end
if scrollView.contentOffset.y >= 0 &&
scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height) {
print("reached end, load more")
// Load more data
loadItems(withDelay: 1)
}
}
Вот как это будет выглядеть:
Если вам трудно следовать какой-то части или добавить ее в свой собственный код, полный код, который может работать как есть, можно найти здесь:
Большое спасибо. Это полезно для меня.
Откуда берутся данные json? У вас есть все данные json в начале или по мере прокрутки вы будете получать их из API?