2017-09-27 1 views
1

J'ai un UITableView avec un délégué de dépôt (iOS 11). Dans ma mise en œuvre deUITableViewDropCoordinator drop (_: toRowAt :) n'effectue pas d'animation

func tableView(_ tableView: UITableView, 
    performDropWith coord: UITableViewDropCoordinator) { 

... J'appelle drop(_:toRowAt:) de coordinateur. Selon Apple, cela devrait entraîner l'animation de l'aperçu de l'élément glisser pour recouvrir la cellule exactement. Mais rien de ce genre ne se passe; l'aperçu de l'élément de glisser est en train de rétrécir, exactement comme si je n'appelais pas du tout drop(_:toRowAt:).

Est-ce que cette commande fait réellement quoi que ce soit?

Répondre

0

UITableViewDropCoordinator drop(_:toRowAt:) fonctionne réellement, mais seulement dans un ensemble très limité de circonstances. Voici ce que vous devez comprendre:

  • drop(_:toRowAt:) doit être appelé dans la partie principale de votre performDropWith mise en œuvre - pas à l'intérieur d'un appel asynchrone loadObject. Cela est vrai pour toutes les commandes UITableViewDropCoordinator drop.

  • drop(_:toRowAt:) fonctionne comme ceci:

    1. D'abord, il instantanés la cellule à la ligne donnée. Puis, il remplace cet instantané par l'aperçu de l'élément de glissement et anime l'instantané pour couvrir la cellule de cette ligne.

Ainsi, drop(_:toRowAt:) est utile que dans un nombre très limité de circonstances. Au moment où vous donnez cette commande, si la cellule en question doit changer son apparence à la suite de la suppression, la cellule doit déjà été rechargée - parce que l'instantané correspondra à l'état de la cellule au moment où le La commande drop est donnée et vous ne voulez pas que l'apparence de la cellule apparaisse en dehors de l'aperçu. Pour cette raison, drop(_:toRowAt:) n'est pas utile en relation avec loadObject. (C'est ce qu'un placeholder est pour.) Il est utile seulement pendant un glisser local où vous pouvez ramasser les données instantanément à partir de localObject de l'élément glisser. Et ce n'est utile que pendant la situation simple où vous déposez sur une cellule existante et remplacer il.

Exemple:

guard let s = item.localObject as? String else {return} 
// ... update model using s ... 
tableView.reloadRows(at: [ip], with: .none) 
coordinator.drop(item, toRowAt: ip) 

Notez que je n'ai pas appel performBatchUpdates. drop(_:toRowAt:) ne fonctionne pas en relation avec performBatchUpdates, car l'instantané sera pris trop tôt. Cela ne fonctionne que dans ce très simple ensemble de circonstances. (Dans la vidéo WWDC sur ce sujet, Apple semble impliquer que drop(_:toRowAt:) correspond en quelque sorte à une intention de baisse de . insertAtDestinationIndexPath.Mais c'est pas vrai. Vous ne pouvez pas supprimer un instantané de la cellule que vous êtes sur le point d'insérer, car vous ne l'avez pas encore inséré. Encore une fois, c'est à cela que sert un espace réservé.)