1

superViewにtapGesture.isがあるときに、collectionViewがdidSelectItemAtIndexPathを呼び出さなかったのはなぜですか?
レスポンダーチェーンに従って "doGesture"が印刷されるのはなぜですか?superViewにジェスチャがあるときに、collectionViewはdidSelectItemAtIndexPathを呼び出さなかった

  1. initCollectionViewは、iPhoneでself.viewに
  2. クリック項目を
  3. addTapGestureをself.viewに追加します。
  4. didSelectItemAtIndexPathを呼び出しません。

    - (void)viewDidLoad { 
        [super viewDidLoad]; 
        UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 
        self.collectionView = [[MyCollectionView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 100) collectionViewLayout:flowLayout]; 
        [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"abc"]; 
        self.collectionView.delegate = self; 
        self.collectionView.dataSource = self; 
        [self.view addSubview:self.collectionView]; 
    
        UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doGesture)]; 
        tapGesture.delegate = self; 
        [self.view addGestureRecognizer:tapGesture]; 
    } 
    
    - (void)doGesture 
    { 
        NSLog(@"%@",@"doGesture"); 
    } 
    
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
    { 
        return 100; 
    } 
    
    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 
    { 
        NSLog(@"%@",@"didSelectItemAtIndexPath"); 
    } 
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 
    { 
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"abc" forIndexPath:indexPath]; 
        if (indexPath.row %2==0) { 
         cell.backgroundColor = [UIColor redColor]; 
        } else{ 
         cell.backgroundColor = [UIColor grayColor]; 
        } 
        return cell; 
    } 
    
+0

"not did didCelectItemAtIndexPath" doGestureを呼び出しましたか? - 別の言い方をしてみましょう。 '[self.view addGestureRecognizer:tapGesture]'行を削除したとします。 _Now_セル選択は機能しますか? – matt

+0

なぜcollectionViewにジェスチャーを追加していますか?フロー/機能要件は何ですか? –

答えて

2

あなたがtapGesture.cancelsTouchesInView = NOを設定する必要があります。

ロジックにもよりますが、delaysTouchesBeganもチェックアウトしてください。アップルのドキュメントから

は:

このプロパティの値がfalse(デフォルト)で、ビューが始まった中 タッチイベントを分析し、受信機と平行に移動しました。 プロパティの値がtrueの場合、ウィンドウはUITouchPhaseBeganフェーズの タッチオブジェクトのビューへの配信を中断します。 ジェスチャ認識プログラムが後でそのジェスチャを認識すると、これらのタッチ オブジェクトは破棄されます。しかし、ジェスチャ認識プログラムがそのジェスチャを認識しない場合、ウィンドウはtouchesBegan(:with :)メッセージの ビュー(これらのオブジェクトをビューtouchesMoved(:with :)への接触の現在の 所在地)をお知らせください。ビューが処理されないようにするには、このプロパティをtrueに設定してください。 このジェスチャの一部として と認識される可能性のあるUITouchPhaseBeganフェーズのすべてのタッチ。

編集:私は、ユーザーがコレクションビュー上でタップすると、ジェスチャー認識の取り扱いをフィルタリングするためのコードスニペットを追加してい完全性については 。私のアプローチは、@ DonMagの答えで言及されたアプローチとは異なります。

- (void)doGesture:(UIGestureRecognizer*) sender 
{  
    CGPoint locationInView = [sender locationOfTouch:0 inView:self.view]; 
    CGPojnt convertedLocation = [self.collectionView convertPoint:location fromView:self.view]; 

    // from Apple doc 
    // Returns a Boolean value indicating whether the receiver contains the specified point. 
    if (![self.collectionView pointInside:convertedLocation withEvent:nil]) 
    { 
     NSLog(@"%@",@"doGesture");   
    } 
} 

EDIT 2: たぶん明確なジェスチャー認識機能についての説明とその仕組み、ビューに追加しました:

すべてのジェスチャー認識は、1つのビューに関連付けられています。対照的に、 ビューは、単一のビュー が多くの異なるジェスチャーに応答する可能性があるため、複数のジェスチャー認識プログラムを持つことができます。ジェスチャ認識ツール に特定のビューで発生した接触を認識するには、そのビューに ジェスチャ認識ツールを接続する必要があります。ユーザーがそのビューにタッチすると、 ジェスチャ認識プログラムは、 ビューオブジェクトの前にタッチが発生したというメッセージを受け取ります。その結果、ジェスチャ認識機能は、ビューに代わって タッチに応答することができます。

+0

ありがとうございます!結果は "doGesture"と "didSelectItemAtIndexPath"と表示されますが、レスポンダチェーンに従って "doGesture"が印刷されるのはなぜですか? – code

+0

あなたが追加するジェスチャレコグナイザは、コレクションビューの親ビューにあります。コレクションビューをタップするときに、ジェスチャ認識プログラムをフィルタリングするための別のアプローチでコードスニペットを追加しました。 –

+0

私はちょうどtouchViewイベントを処理するためにデフォルトでcollectionViewを理解できません – code

0

設定tapGesture.cancelsTouchesInView = NO

これは、あなたが tapGestureイベントを取得することcollectionView didSelectItemAtIndexPath

注意として、他のビューの内部のタッチが通過することができます。あなたはcollectionViewCellがタップされたときにことを無視したい場合は、このデリゲートメソッドを追加します。

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ 
    CGPoint touchPoint = [touch locationInView:self.collectionView]; 
    return ![self.collectionView hitTest:touchPoint withEvent:nil]; 
} 
0

「doGestureは」あなたがあなたの全体の上にタップ認識を追加しましたので、期待通りに働いている、ログに表示された場合ビュー。タップを認識させ、didSelectを呼び出すには、タップコードからdidSelectを呼び出す必要があります。

let locationInView: CGPoint = tapGesture.location(in: self.view) 
let locationInCollectionView: CGPoint = tapGesture.location(in: self.collectionView) 
if let indexPath: IndexPath = collectionView.indexPathForItem(at: locationInCollectionView) { 
    collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .centeredVertically) 

}

関連する問題