web-dev-qa-db-fra.com

Le rechargement d'un UICollectionView à l'aide de la méthode reloadData renvoie immédiatement avant le rechargement des données

J'ai besoin de savoir lorsque le rechargement d'un UICollectionView est terminé afin de configurer les cellules par la suite (parce que je ne suis pas la source de données pour les cellules - sinon, je l'aurais déjà fait ...)

J'ai essayé du code tel que

[self.collectionView reloadData];
[self configure cells]; // BOOM! cells are nil

J'ai aussi essayé d'utiliser

[self.collectionView performBatchUpdates:^{
  [self.collectionView reloadData];
    } completion:^(BOOL finished) {
        // notify that completed and do the configuration now
  }];

mais quand je recharge les données, je me bloque.

Comment puis-je recharger les données dans la collection, et seulement une fois le rechargement terminé - faire un gestionnaire d'achèvement particulier

23
Avner Barr

Cela est dû au fait que des cellules sont ajoutées lors de layoutSubviews et non à reloadData. Puisque layoutSubviews est effectué lors de la prochaine passe de boucle d'exécution après reloadData, vos cellules sont vides. Essayez de faire ceci:

[self.collectionView reloadData];
[self.collectionView layoutIfNeeded];
[self configure cells]; 

J'ai eu un problème similaire et l'ai résolu de cette façon.

94
lukewar

La vue de collection n'est pas prise en charge pour être rechargée de manière animée à l'aide de reloadData. Toutes les animations doivent être exécutées avec des méthodes, telles que

[collectionView deleteItemsAtIndexPaths:indexesToDelete];
[collectionView insertSections:sectionsToInsert];
[collectionView reloadItemsAtIndexPaths:fooPaths];

à l'intérieur de performBatchUpdates: bloquer. Cette méthode reloadData ne peut être utilisée que pour un rafraîchissement approximatif, lorsque tous les éléments sont supprimés et disposés à nouveau sans animation.

5
kelin

Si vous souhaitez exécuter du code une fois que votre collectionView a terminé sa méthode reloadData (), essayez ceci (Swift):

    self.collectionView.reloadData()
    self.collectionView.layoutIfNeeded()
    dispatch_async(dispatch_get_main_queue()) { () -> Void in
        // Put the code you want to execute when reloadData is complete in here
    }

La raison pour laquelle cela fonctionne est que le code dans le bloc de répartition est placé à l'arrière de la ligne (également appelé file d'attente). Cela signifie qu'il attend en ligne que toutes les opérations du thread principal se terminent, y compris les méthodes de reloadData (), avant qu'il ne devienne, il active le thread principal.

4
Alan Scarpa