Je veux faire défiler jusqu'à un index donné (self.boldRowPath
), mais lorsque je débogue scrollToRow
est effectué avant reloadData()
.
Comment savoir que reloadData
a fini?
func getAllTimeEvent() {
self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo)
self.tblTimeEvent.reloadData()
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
}
Toute aide sera très appréciée.
Essayez de faire ça, ça devrait marcher:
self.tblTimeEvent.reloadData()
DispatchQueue.main.async(execute: {
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
})
Ceci exécutera le scrollToRow sur le thread principal, ce qui signifie qu'après que reloadData soit terminé (car il se trouve sur le thread principal)
Comme expliqué dans cette réponse , le rechargement de la UITableView
a lieu à la prochaine exécution de la présentation (généralement lorsque vous redonnez le contrôle à la boucle d'exécution).
Ainsi, vous pouvez planifier votre code après la mise en page suivante en utilisant la file d'attente de répartition principale. Dans ton cas:
func getAllTimeEvent() {
self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo)
self.tblTimeEvent.reloadData()
DispatchQueue.main.async {
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
}
}
Vous pouvez également forcer la mise en page en appelant manuellement layoutIfNeeded
. Mais ce n’est généralement pas une bonne idée (l’option précédente est la meilleure):
func getAllTimeEvent() {
self.arrAllTimeEvent = ModelManager.getInstance().getAllTimeEvent(from: self.apportmentDateFrom, to: self.apportmentDateTo)
self.tblTimeEvent.reloadData()
self.tblTimeEvent.layoutIfNeeded()
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
}
Vous pouvez faire une hypothèse assez solide selon laquelle une UITableView
est rechargée lors du dernier appel de tableView(_:willDisplay:forRowAt:)
pour les sections visibles à l'écran.
Essayez donc quelque chose comme ceci (pour un tableau où les lignes de la section 0 occupent l’espace disponible à l’écran):
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastRowIndex = tableView.numberOfRows(inSection: 0)
if indexPath.row == lastRowIndex - 1 {
// tableView done reloading
self.tblTimeEvent.scrollToRow(at: self.boldRowPath ?? [0,0], at: .top, animated: true)
}
}
vous pouvez vous assurer que le rechargement est terminé en utilisant ...
Dans Swift 3.0 + nous pouvons créer une extension pour UITableView
avec un escaped Closure
comme ci-dessous:
extension UITableView {
func reloadData(completion: @escaping () -> ()) {
UIView.animate(withDuration: 0, animations: { self.reloadData()})
{_ in completion() }
}
}
Et utilisez-le comme ci-dessous où vous voulez:
Your_Table_View.reloadData {
print("reload done")
}
espérons que cela aidera à quelqu'un. à votre santé!