如何检测UICollectionView中单元格的双击

我想要对UICollectionView中的单元格进行双击,并有一个双击动作取消单元格select。

这是我试过的:

UITapGestureRecognizer *tapRecogniser = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)]; tapRecogniser.numberOfTapsRequired = 2; for (UITapGestureRecognizer *recogniser in [self.collectionView gestureRecognizers]) { [recogniser requireGestureRecognizerToFail:tapRecogniser]; } [self.collectionView addGestureRecognizer:tapRecogniser]; 

也就是说,如果我的双击手势识别器成功,我试图让默认的手势识别器失败。

这似乎不工作,因为我的集合视图委托的collectionView:didSelectItemAtIndexPath:仍然被调用后,双击


请注意Apple的UICollectionViewController文档

苹果公司的文档在这一点上是误导性的,声称默认的手势识别器是UITapGestureRecognizer子类的一个实例,所以它可以很容易地用[recogniser isKindOfClass:[UITapGestureRecognizer class]]来挑选出来。 不幸的是,这是一个错误。

我不明白你为什么需要requireToFail。 我在UICollectionView中使用双击,它不会干扰我的单击(用于select)。

我使用以下内容:

 UITapGestureRecognizer *doubleTapFolderGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(processDoubleTap:)]; [doubleTapFolderGesture setNumberOfTapsRequired:2]; [doubleTapFolderGesture setNumberOfTouchesRequired:1]; [self.view addGestureRecognizer:doubleTapFolderGesture]; 

那么,这个:

 - (void) processDoubleTap:(UITapGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateEnded) { CGPoint point = [sender locationInView:collectionView]; NSIndexPath *indexPath = [collectionView indexPathForItemAtPoint:point]; if (indexPath) { NSLog(@"Image was double tapped"); } else { DoSomeOtherStuffHereThatIsntRelated; } } } 

似乎工作正常 – 双击是公认的,我可以处理它,因为我希望(在这种情况下,我扩大了文件夹的内容)。 但是单击会导致被窃听的卖出被选中,我没有写出任何手势识别。

重要编辑:

我正在重新审视这个问题,因为我已经看到,在某些情况下,我的原始答案可能是错的,而且似乎有一个明显的解决办法。

需要添加以下行:

 doubleTapFolderGesture.delaysTouchesBegan = YES; 

这消除了用于单元select的单个抽头的干扰。 这提供了一个更强大的设置。

在这里有一堆很好的解决scheme,但不幸的是,他们没有为我工作可靠(例如,我不能得到双击,一致触发可能是因为我也实施了didSelectItemAtIndexPath)。

什么对我来说是添加(双)轻拍手势识别器的集合视图,而不是单元格。 在它的动作select器中,我将确定哪个单元格被双击,并做我需要做的事情。 希望这有助于某人:

 - (void)viewDidLoad { UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didDoubleTapCollectionView:)]; doubleTapGesture.numberOfTapsRequired = 2; [self.collectionView addGestureRecognizer:doubleTapGesture]; } - (void)didDoubleTapCollectionView:(UITapGestureRecognizer *)gesture { CGPoint pointInCollectionView = [gesture locationInView:self.collectionView]; NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:pointInCollectionView]; UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:selectedIndexPath]; // do something } 

我的解决scheme是不实现collectionView:didSelectItemAtIndexPath,但实现两个手势识别器。

  self.doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(processDoubleTap:)]; [_doubleTapGesture setNumberOfTapsRequired:2]; [_doubleTapGesture setNumberOfTouchesRequired:1]; [self.view addGestureRecognizer:_doubleTapGesture]; self.singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(processSingleTap:)]; [_singleTapGesture setNumberOfTapsRequired:1]; [_singleTapGesture setNumberOfTouchesRequired:1]; [_singleTapGesture requireGestureRecognizerToFail:_doubleTapGesture]; [self.view addGestureRecognizer:_singleTapGesture]; 

这样我可以处理单击和双击。 我能看到的唯一问题是单元格是在doubleTaps上选中的,但是如果这个问题困扰,你可以在两个select器中处理它。

在默认手势识别器上调用的requireGestureRecognizerToFail:实际上是工作的(也就是说,如果识别到双击,它们的状态转到UIGestureRecognizerStateFailed)。

但它似乎UICollectionView的collectionView:didSelectItemAtIndexPath:委托callback不考虑到这一点,即。 当默认的手势识别器失败时,它仍然被调用。

所以答案/解决方法是确保委托的collectionView:shouldSelectItemAtIndexPath:collectionView:shouldDeselectItemAtIndexPath:实现检查默认手势识别器的状态(?)之一,因此:

 - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath { UITapGestureRecognizer *defaultGestureRecogniser = [[self.collectionView gestureRecognizers] objectAtIndex:0]; return defaultGestureRecogniser.state != UIGestureRecognizerStateFailed; }