6

この質問と同様の問題で、インスタンスにダブルタップ ジェスチャ認識エンジンを追加しようとしていUICollectionViewます。

デフォルトのシングル タップでUICollectionViewDelegateメソッドが呼び出されないようにする必要がありますcollectionView:didSelectItemAtIndexPath:

これを実現するために、Apple のコレクション ビュー プログラミング ガイド(リスト 4-2)から直接コードを実装します。

UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
NSArray* recognizers = [self.collectionView gestureRecognizers];

// Make the default gesture recognizer wait until the custom one fails.
for (UIGestureRecognizer* aRecognizer in recognizers) {
   if ([aRecognizer isKindOfClass:[UITapGestureRecognizer class]])
      [aRecognizer requireGestureRecognizerToFail:tapGesture];
}

// Now add the gesture recognizer to the collection view.
tapGesture.numberOfTapsRequired = 2;
[self.collectionView addGestureRecognizer:tapGesture];

このコードは期待どおりに動作しません。tapGestureダブル タップで起動しますが、既定のシングル タップは防止されず、デリゲートのdidSelect...メソッドは引き続き呼び出されます。

デバッガーをステップ実行すると、if 条件[aRecognizer isKindOfClass:[UITapGestureRecognizer class]]が true に評価されないため、新しい条件の失敗要件tapGestureが確立されていないことがわかります。

for ループのたびに次のデバッガー コマンドを実行します。

po (void)NSLog(@"%@",(NSString *)NSStringFromClass([aRecognizer class]))

デフォルトのジェスチャ レコグナイザーは (実際には)UITapGestureRecognizerインスタンスではないことがわかります。

代わりに、プライベート クラスUIScrollViewDelayedTouchesBeganGestureRecognizerUIScrollViewPanGestureRecognizer.

まず、プライベート API に関する規則に違反しない限り、これらを明示的に使用することはできません。UIScrollViewDelayedTouchesBeganGestureRecognizer第 2 に、ビアにアタッチしてrequireGestureRecognizerToFail:も目的の動作が得られないようです。つまり、デリゲートdidSelect...がまだ呼び出されています。

UICollectionViewのデフォルトのジェスチャ認識機能を使用して、コレクション ビューにダブル タップを追加し、デフォルトのシングル タップでもデリゲートのcollectionView:didSelectItemAtIndexPath:メソッドが起動されないようにするにはどうすればよいですか?

前もって感謝します!

4

2 に答える 2

4

以下を使用して UITapGestureRecognizer を登録します。

UITapGestureRecognizer* singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTapGesture:)];
singleTapGesture.delaysTouchesBegan = YES;
singleTapGesture.numberOfTapsRequired = 1; // number of taps required
singleTapGesture.numberOfTouchesRequired = 1; // number of finger touches required
[self.collectionView addGestureRecognizer:singleTapGesture];

カスタム ジェスチャ レコグナイザーに設定delaysTouchesBeganするとYES、他のタッチ イベントの登録を遅らせることで、既定のコレクション ビュー タップ リスナーよりも優先されます。または、 を に設定して、タッチ認識を完全にキャンセルするように設定することもできcancelsTouchesInViewますYES

ジェスチャは、次の関数によって処理されます。

- (void)handleSingleTapGesture:(UITapGestureRecognizer *)sender {

    if (sender.state == UIGestureRecognizerStateEnded) {
        CGPoint location = [sender locationInView:self.collectionsView];
        NSIndexPath *indexPath = [self.collectionsView indexPathForItemAtPoint:location];

        if (indexPath) {
            NSLog(@"Cell view was tapped.");
            UICollectionViewCell *cell = [self.collectionsView cellForItemAtIndexPath:indexPath];
            // Do something.                
        }
    }
    else{
        // Handle other UIGestureRecognizerState's
    }
}
于 2015-02-03T10:57:07.333 に答える