押したときにUILongPressGestureRecognizerが2回呼び出される


359

ユーザーが2秒間押し続けたかどうかを検出しています。

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
                                             initWithTarget:self 
                                             action:@selector(handleLongPress:)];
        longPress.minimumPressDuration = 2.0;
        [self addGestureRecognizer:longPress];
        [longPress release];

これは私が長押しを処理する方法です:

-(void)handleLongPress:(UILongPressGestureRecognizer*)recognizer{
    NSLog(@"double oo");
}

2秒以上押し続けると、「double oo」というテキストが2回印刷されます。どうしてこれなの?どうすれば修正できますか?

回答:


684

UILongPressGestureRecognizerは、継続的なイベント認識機能です。状態を見て、これがイベントの開始、中間、または終了であるかどうかを確認し、それに応じて行動する必要があります。つまり、開始後にすべてのイベントを破棄するか、必要に応じて動きだけを見ることができます。クラスリファレンスから :

長押しジェスチャーは連続しています。許容される指の数(numberOfTouchesRequired)が指定された期間(minimumPressDuration)押され、タッチが許容される移動範囲(allowableMovement)を超えて移動しないと、ジェスチャーが開始(UIGestureRecognizerStateBegan)します。ジェスチャレコグナイザは、指が動くたびにChange状態に移行し、いずれかの指が離されると終了します(UIGestureRecognizerStateEnded)。

これで、このように状態を追跡できます

-  (void)handleLongPress:(UILongPressGestureRecognizer*)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) {
      NSLog(@"UIGestureRecognizerStateEnded");
    //Do Whatever You want on End of Gesture
     }
    else if (sender.state == UIGestureRecognizerStateBegan){
       NSLog(@"UIGestureRecognizerStateBegan.");
   //Do Whatever You want on Began of Gesture
     }
  }

4
次の答えはその方法を示していますが、詳細な説明とドキュメントへのリンクがあるため、この答えを+1にしました。
Matt Connolly

2
ドキュメントだけにリンクするのではなく、コード例を参考にするとよいでしょう。以下のコードスニペットを投稿しました。UIGestureRecognizerStateBegan状態を確認してください。
Paul Solt、2011

UIGestureRecognizerStateChanged
Rajneesh071

@joelmあなたは私を救った)
Evgeniy Kleban

Swift 4の場合:if(sender.state == UITapGestureRecognizer.State.ended){//ジェスチャーの終わりに何でもしたいprint( "\ n * longpressed * \ n")}
Ravi

117

UILongPressGestureRecognizerの状態を確認するには、selectorメソッドにifステートメントを追加します。

- (void)handleLongPress:(UILongPressGestureRecognizer *)sender {    
    if (sender.state == UIGestureRecognizerStateEnded) {
        NSLog(@"Long press Ended");
    } else if (sender.state == UIGestureRecognizerStateBegan) {
        NSLog(@"Long press detected.");
    }
}

13
終了よりも多くの状態があるため、if / elseブロックは必要ありません。状態が変化すると、「長押しが検出されました」が複数回印刷されます。代わりに、UIGestureRecognizerStateBegan状態を確認してください。
Paul Solt、2011

2
誰かが実際にその回答を編集して、トップのコメントの内容に合わせる必要があります。現状では、提供されたコードは機能しません。
Declan McKenna 2012

75

状態ごとに異なる動作があるため、正しい状態を確認する必要があります。ほとんどの場合、UIGestureRecognizerStateBegan状態が必要になりますUILongPressGestureRecognizer

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
                                             initWithTarget:self 
                                             action:@selector(handleLongPress:)];
longPress.minimumPressDuration = 1.0;
[myView addGestureRecognizer:longPress];
[longPress release];

...

- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
    if(UIGestureRecognizerStateBegan == gesture.state) {
        // Called on start of gesture, do work here
    }

    if(UIGestureRecognizerStateChanged == gesture.state) {
        // Do repeated work here (repeats continuously) while finger is down
    }

    if(UIGestureRecognizerStateEnded == gesture.state) {
        // Do end work here when finger is lifted
    }
}

2
状態を変更するには指を動かす必要があるようです。あれは正しいですか?
アルカディアン2012年

指を動かすとStateChangedがトリガーされる可能性があります。これは、テストコードで行っていた操作に似ています。
ポールソルト2012年

UIGestureRecognizerStateBeganは1回しか呼び出されないようです。これは、ボタンの長押しを検出したときにダイアログを表示しようとする私の状況に最適です。他の状態は複数回呼び出されます。ありがとう!
ダミアン

19

ちょうどこれを試してください:

Objective-C

- (void)handleLongPress:(UILongPressGestureRecognizer*)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) {
        NSLog(@"Long press Ended");
    } else if (sender.state == UIGestureRecognizerStateBegan) {
        NSLog(@"Long press detected.");
    }
}

Swift 2.2:

func handleLongPress(sender:UILongPressGestureRecognizer) {

        if (sender.state == UIGestureRecognizerState.Ended) {
            print("Long press Ended");
        } else if (sender.state == UIGestureRecognizerState.Began) {
            print("Long press detected.");
        }
}

14

Swiftでの処理方法は次のとおりです。

func longPress(sender:UILongPressGestureRecognizer!) {

        if (sender.state == UIGestureRecognizerState.Ended) {
            println("Long press Ended");
        } else if (sender.state == UIGestureRecognizerState.Began) {
            println("Long press detected.");
        }
}

13

Swift 3.0:

func handleLongPress(sender: UILongPressGestureRecognizer) {

    if sender.state == .ended {
        print("Long press Ended")
    } else if sender.state == .began {
        print("Long press detected")
    }

6

ジェスチャーハンドラーは、ジェスチャーの各状態の呼び出しを受け取ります。したがって、各状態をチェックして、コードを必要な状態にする必要があります。

if-elseよりもswitch-caseの使用を好む必要があります。

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
                                         initWithTarget:self 
                                         action:@selector(handleLongPress:)];
    longPress.minimumPressDuration = 1.0;
    [myView addGestureRecognizer:longPress];
    [longPress release];

-(void)handleLongPress:(UILongPressGestureRecognizer *)gesture {
        switch(gesture.state){
          case UIGestureRecognizerStateBegan:
               NSLog(@"State Began");
               break;
          case UIGestureRecognizerStateChanged:
               NSLog(@"State changed");
               break;
          case UIGestureRecognizerStateEnded:
               NSLog(@"State End");
               break;
          default:
               break;
         }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.