Вы должны удалить self.collectionVitrin.reloadData()
, вызываемый сразу после LoadDatas(limit: 20)
в вашей функции willDisplay
.
Но если я могу дать вам совет по реализации бесконечной прокрутки в представлении коллекции, я бы изменил кое-что.
Прежде всего, я бы посоветовал вам изменить свой вызов API.Вам следует сохранить ограничение на количество элементов, отправляемых обратно из каждого вызова API, но также реализовать переменную смещения.Это гораздо эффективнее.
В вашем случае ваш второй вызов API просто снова запрашивает те же объекты с большим лимитом в запросе.Вы в основном запрашиваете одни и те же данные каждый раз.Добавление смещения позволяет запрашивать только новые данные каждый раз.Это смещение должно соответствовать объему данных, которые у вас уже есть.
Во-вторых, вы должны попытаться добавить отказоустойчивый механизм, когда достигнете конца своих данных или когда вы уже запрашиваете данные.В противном случае вы в конечном итоге будете зацикливаться на вызовах, если достигнете нижней части окна сбора.Вот как я бы реализовал бесконечную загрузку на основе вашего кода
@IBOutlet weak var collectionVitrin: UICollectionView!
var limitPerCall: Int = 10
var isLoadindNewData = false
var shouldLoadMoreData = true
var vitrinDecodePost = [VitrinDecode]() // Decodable
func loadDatas(limit : Int, offset: Int) {
guard let url = URL(string: "my Url") else { return }
let session = URLSession.shared
let request = NSMutableURLRequest(url: url as URL)
request.httpMethod = "POST"
let parameters = ["limit": "\(limit)", "offset": "\(offset)"] as Dictionary<String, String>
guard let httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: []) else { return }
request.httpBody = httpBody
let task = session.dataTask(with: request as URLRequest) { [weak self]
(data, response, error) in
guard let strongSelf = self, let _:NSData = data as NSData? , let _:URLResponse = response, error == nil else {
print("Mistake")
return
}
/// No More data to gather stop making api calls
guard let data = data else {
strongSelf.shouldLoadMoreData = false
return
}
do {
let abc = try JSONDecoder().decode([VitrinDecode].self, from: data)
strongSelf.vitrinDecodePost.append(contentsOf: abc)
//// Reload the new data and and indicates that api call can be
made again
DispatchQueue.main.async {
strongSelf.isLoadingNewData = false
strongSelf.collectionVitrin.reloadData()
}
} catch { print(error)}
}
task.resume()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection
section: Int) -> Int {
return self.vitrinDecodePost.count
}
func collectionView(_ collectionView: UICollectionView, willDisplay cell:
UICollectionViewCell, forItemAt indexPath: IndexPath) {
let lastindex = self.vitrinDecodePost.count - 1
if indexPath.row == lastindex && !isLoadindNewData && shouldLoadMoreData {
/// Forbids multiple api calls to happen at the same time
isLoadindNewData = true
loadDatas(limit: limitPerCall, offset: vitrinDecodePost.count)
}
}
Надеюсь, это поможет.
Best