web-dev-qa-db-fra.com

Comment ajouter un geste de prise à UICollectionView, tout en conservant la sélection des cellules?

Tâche

Ajoutez un geste de simple pression sur UICollectionView, ne gênez pas la sélection des cellules.

Je veux quelques autres robinets sur la partie sans cellule de la collectionView.

Code

En utilisant XCode8, Swift 3.

override func viewDidLoad() {
    ...
    collectionView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tap)))
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print(indexPath)
}

func tap(sender: UITapGestureRecognizer){
    print("tapped")
}

Résultat

Ouais, ça gêne maintenant. Lorsque vous appuyez sur la cellule, elle enregistre "tapé".

Une analyse

  • Je vérifie la valeur de retour hitTest de la collectionView et de la cellule. Les deux ont renvoyé la cellule tapée, ce qui signifie qu'ils forment une chaîne de réponse de Cell -> CollectionView
  • pas de gestes sur la cellule
  • 3 gestes sur collectionView, personne ne semble fonctionner avec la cellule sélectionnez
    • UIScrollViewDelayedTouchesBeganGestureRecognizer
    • UIScrollViewPanGestureRecognizer
    • UITapGestureRecognizer
  • callStack, la sélection de cellules semble avoir une trace de pile différente avec le modèle d'action cible du geste.
  • le geste de double appui fonctionne avec la sélection de cellules.

Question

Impossible de trouver plus de trace. Avez-vous des idées sur la façon dont la sélection des cellules est mise en œuvre ou pour réaliser cette tâche?

19
jchnxu

Chaque fois que vous souhaitez ajouter un identificateur de mouvement, mais pas voler les touches de la vue cible, vous devez définir UIGestureRecognizer.cancelsTouchesInView pour votre gestureRecognizer instance sur false.

28
Josh Homann

Au lieu d'essayer de forcer didSelectItem, vous pouvez simplement obtenir l'indexPath et/ou la cellule de cette façon:

func tap(sender: UITapGestureRecognizer){

    if let indexPath = self.collectionView?.indexPathForItem(at: sender.location(in: self.collectionView)) {
        let cell = self.collectionView?.cellForItem(at: indexPath)
        print("you can do something with the cell or index path here")
    } else {
        print("collection view was tapped")
    }
}
11
Frankie