web-dev-qa-db-fra.com

Comment savoir reloadData () est terminée sa tâche?

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.

8
Harshil Kotecha

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)

14
Farid Al Haddad

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)
    }
5
Julien Quere

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)
  }
}
1
Andy Obusek

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é!

0
Anuradh S