Je me demande si tableview a une fonction intégrée pour ajouter un défilement/une pagination infinis.
En ce moment, mon VC ressemble à ceci:
var data: JSON! = []
override func viewDidLoad() {
super.viewDidLoad()
//Init start height of cell
self.tableView.estimatedRowHeight = 122
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.delegate = self
self.tableView.dataSource = self
savedLoader.startAnimation()
//Load first page
loadSaved(1)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("aCell") as! SavedTableViewCell
let info = data[indexPath.row]
cell.configureWithData(info)
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
performSegueWithIdentifier("WebSegue", sender: indexPath)
tableView.deselectRowAtIndexPath(indexPath, animated: false)
}
Je récupère mes données en utilisant loadSaved (1)} _ en donnant à la fonction la page en cours que je veux charger. La fonction effectue une demande d'API à l'aide d'alomofire, puis renseigne le var data: JSON! = [] Avec les données à afficher.
Donc, ce que je veux faire, c’est que lorsque je fais défiler vers le bas de la vue tableau loadSaved (2)} devrait être appelé charger plus de données dans la vue tableau
UITableViewDelegate a une méthode d'instance Table View (_: affichera: pour la ligne à:) } qui indique au délégué que la vue de table est sur le point de dessiner une cellule pour une ligne particulière . "
Dans votre cas, je l’utiliserais comme ceci:
override open func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == data.count-1 { //you might decide to load sooner than -1 I guess...
//load more into data here
}
}
En fonction de votre code, vous aurez peut-être besoin de quelques vérifications pour vous assurer de ne pas vous retrouver dans une boucle infinie si vous avez chargé toutes vos données ...
Non, la UITableView
n'a pas de fonction intégrée permettant de réaliser le défilement infini ou le chargement de cellules à la demande comme vous le souhaitez. Ce que vous pouvez utiliser est la fonction scrollViewDidScroll(_:)
dans la UIScrollViewDelegate
implémentée par défaut dans la UITableView
et vous permet ainsi de savoir quand l'utilisateur fait défiler plus que la hauteur d'origine définie dans la UITableView
.
Par exemple, comme dans ce code:
var indexOfPageToRequest = 1
override func scrollViewDidScroll(scrollView: UIScrollView) {
// calculates where the user is in the y-axis
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.size.height {
// increments the number of the page to request
indexOfPageToRequest += 1
// call your API for more data
loadSaved(indexOfPageToRequest)
// tell the table view to reload with the new data
self.tableView.reloadData()
}
}
Pour obtenir le résultat de l'ajout du reste des éléments à la fin de la UITableView
, vous devez ajouter les nouveaux éléments à la source de données, dans votre cas data
à l'intérieur de votre fonction loadSaved(numberOfPage)
.
J'espère que cela vous aidera.
J'ai modifié la réponse de Victor et l'ai utilisée comme,
var indexOfPageRequest = 1
var loadingStatus = false
func loadData(){
if !loadingStatus{
loadingStatus = true
viewModel.getData(pageIndex: indexOfPageRequest)
}
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
// calculates where the user is in the y-axis
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.size.height {
// increments the number of the page to request
indexOfPageRequest += 1
// call your API for more data
loadData()
// tell the table view to reload with the new data
self.tableView.reloadData()
}
}
Réinitialisez loadingStatus sur true lorsque vous recevez des données. Sans vérifier si la vue chargeait déjà plus de données, la vue table scintillait.
Toutes les réponses ci-dessus sont correctes, mais pour iOS 10 et plus, nous avons une très belle
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath])
Ceci est un délégué prefetch qui doit être défini
tableView.prefetchDataSource = self
RayWeinderlich a un bon tutoriel sur le sujet. Puisque Rays est un site fiable, je ne poste pas de code ici
Ci-dessus Et ont également raison, mais peut-être que quelqu'un aidera ce code également.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath){
if(indexPath.row == self.arryOfData.count-1){
if(self.pageNumber <= self.resPgNumber){
if(remaining != 0){
let spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray)
spinner.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(44))
spinner.startAnimating()
tableView.tableFooterView = spinner
tableView.tableFooterView?.isHidden = false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.flgActivity = false
self.getActiveOrdersList()
}
}
else{
tableView.tableFooterView?.removeFromSuperview()
let view = UIView()
view.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(5))
tableView.tableFooterView = view
tableView.tableFooterView?.isHidden = true
}
}
else{
tableView.tableFooterView?.removeFromSuperview()
let view = UIView()
view.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(5))
tableView.tableFooterView = view
tableView.tableFooterView?.isHidden = true
}
}
else{
tableView.tableFooterView?.removeFromSuperview()
let view = UIView()
view.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.bounds.width, height: CGFloat(5))
tableView.tableFooterView = view
tableView.tableFooterView?.isHidden = true
}
}
La réponse de Ravi est bonne. Mais comme il l’a souligné à la fin, la tableView scintille beaucoup si vous utilisez scrollViewDidScroll(_ scrollView: UIScrollView)
En effet, vous essayez de recharger tableView chaque fois que vous faites défiler tableView.
À la place, vous pouvez utiliser la méthode déléguée scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
pour déterminer si vous avez suffisamment défilé et si vous avez presque atteint la fin de la tableView.
override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.size.height {
indexOfPageRequest += 1
loadData()
self.tableView.reloadData()
}
}