Pass touche une partie de UICollectionView aux vues sous-jacentes

Jetez d'abord un coup d'oeil à l'image attacthed: entrez la description de l'image ici

Ma hiearchy ressemble à ceci:

  • UIView
    • UIButton
    • UICollectionView
      • UICollectionViewCell
      • UICollectionViewCell
      • UICollectionViewCell
      • UICollectionViewCell

UICollectionView est ajouté à UIVew en tant que H:[collectionView(==270)]| et V:|-(70)-[collectionView]-(70)-| .

J'ai deux exigences:

1) seule la partie bleue de UICollectionViewCell doit triggersr la méthode collectionView::didSelectItemAtIndexPath: Ce que j'ai réussi à mettre en œuvre avec

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *hitView = [super hitTest:point withEvent:event]; if (hitView == self.customView) { return self; } return nil; } 

dans la class personnalisée UIColectionViewCell. La propriété customView est l' customView bleu / rouge de la cellule. Cela fonctionne comme prévu.

2) Je veux que tous les gestes (Tap / LongTap / Pan / …) qui sont effectués dans la partie verte de UICollectionViewCell ou dans le UICollectionVIew lui-même (l'arrière-plan blanc ici avec 0.5 opacité) soient transmis à la vue d'set . Par exemple l'UIButtion turquoise ci-dessous. La partie verte ne doit pas non plus faire défiler la CollectionView. Elle doit simplement être complètement transparente pour tous les gestes.

Comment puis je faire ça? J'ai essayé beaucoup d'approches différentes, mais aucune d'elles n'a fonctionné. Je sais comment le faire avec un UIView régulier, mais je n'arrive pas à le faire fonctionner sur un UICollectionView et ses cellules.

Gardez à l'esprit qu'il y aura d'autres UIViews ou UIButtions qui seront interactives et placés dans la partie verte de la vue de collection. La couleur verte sera plus tard juste UIClearColor.

Suggestion d'avoir juste la plus petite largeur d'UICollectionView (largeur de la partie bleue) n'est pas une option puisque la partie bleue / rouge d'UICell doit dans certains cas s'étendre sur toute la largeur de la cellule.

Votre réponse m'a aidé une tonne, merci!

Voici la solution dans Swift 3.0:

  override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let hitView = super.hitTest(point, with: event) if hitView == self.customView { return self } return nil } 

Voici la solution finale pour l'exemple ci-dessus:

1) Exiger seulement que la partie rouge / bleue soit tappable. Cela rest fondamentalement le même. J'ai une reference aux noms customView bleu / rouge customView

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *hitView = [super hitTest:point withEvent:event]; if (hitView == self.customView) { return self; } return nil; } 

2) Toutes les interactions à l'intérieur de UICollectionView qui ne sont pas effectuées sur les UIViews bleues / rouges doivent être ignorées.

Sous-class UICollectionView et ajout de l'écrasement de cette métode:

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { NSIndexPath *indexPath = [self indexPathForItemAtPoint:point]; LCollectionViewCell *cell = (LCollectionViewCell*)[self cellForItemAtIndexPath:indexPath]; if (cell && [self convertPoint:point toView:cell.customView].x >= 0) { return YES; } return NO; } 

Cela vérifiera si le CGPoint est fait sur le customView . Avec cela, nous supportons également des largeurs variables:

entrez la description de l'image ici