20

UILongPressGestureRecognizerとUIPanGestureRecognizerを組み合わせたいと思います。

UIPanGestureRecognizerは、長押しで開始する必要があります。これを行う簡単な方法はありますか?または、本当に自分のジェスチャレコグナイザーを作成する必要がありますか?

ホーム画面のようなものはしたくない。アイコンを押すと、しばらくするとアイコンがぐらつき始めます。その後、画面から指を離さずに、指の下にあるアイコンをドラッグし始めることができます。

4

7 に答える 7

24

実際には、ジェスチャレコグナイザーを組み合わせる必要はありません。これは、UILongPressGestureRecognizerでのみ行うことができます...タッチが「minimumPressDuration」の「allowableMovement」内にとどまったら、StateBeganに入ります。指を離さない限り、継続的なlongPressGestureに留まります。そのため、指の移動を開始し、StateChangedを介して移動を追跡できます。

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

于 2010-08-26T22:52:07.927 に答える
21

私はこの問題に少し苦労しました。受け入れられた答えは十分ではありませんでした。そのメソッドに何を入れても、panまたはlongpressハンドラーが呼び出されます。私が見つけた解決策は次のとおりです。

  1. ジェスチャレコグナイザーのデリゲートが同じクラス(私の場合は自分自身)に割り当てられていることを確認し、デリゲートクラスがであることを確認しUIGestureRecognizerDelegateます。
  2. 次のデリゲートメソッドをクラスに追加します(上記の回答に従って)。

    - (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
    shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 
         return YES;
    }
    
  3. 次のデリゲートメソッドをクラスに追加します。

    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
         if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ! shouldAllowPan) {
              return NO;
         }
         return YES;
    }
    
  4. 次に、パンの開始を許可する必要があるかどうかを追跡するプロパティまたはivarを追加します(上記の方法を参照)。私の場合BOOL shouldAllowPan

  5. BOOLをまたはに設定NOします。longPressハンドラー内で、BOOLをに設定します。私はこのようにします:initviewDidLoadYES

    - (void) longPressHandler: (UILongPressGestureRecognizer *) gesture {
    
         if(UIGestureRecognizerStateBegan == gesture.state) {
            shouldAllowPan = NO;
         }
    
         if(UIGestureRecognizerStateChanged == gesture.state) {
            shouldAllowPan = YES;
         }
    }
    
  6. panHandler内で、BOOLをチェックします。

    - (void)panHandler:(UIPanGestureRecognizer *)sender{
        if(shouldAllowPan) {
              // do your stuff
        }
    
  7. そして最後に、panHandler内のBOOLをリセットします。

    else if(sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) {
        shouldAllowPan = NO;
    }
    
  8. そして、ビールを飲みに行って、おめでとう。;)

于 2013-10-17T16:14:09.837 に答える
16

私は解決策を見つけました:このUIGestureRecognizerDelegateメソッドは私が探していたものを正確に実行します:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer 
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
于 2010-08-16T12:51:06.420 に答える
11

SwiftでのAndyBの​​アプローチ、

  1. UIGestureRecognizerDelegateデリゲートをクラスに追加します

    class ViewController: UIViewController, UIGestureRecognizerDelegate
    
  2. メンバー変数を追加する

    var shouldAllowPan: Bool = false
    
  3. ジェスチャを追加し、パンジェスチャデリゲートをVCに追加する必要があります。これは、shouldRecognizeSimultaneouslyWithGestureRecognizerおよびgestureRecognizerShouldBegin関数を起動するために必要です。

    // long press
    let longPressRec = UILongPressGestureRecognizer(target: self, action: "longPress:")
    yourView.addGestureRecognizer(longPressRec)
    
    // drag
    let panRec = UIPanGestureRecognizer(target: self, action: "draggedView:")
    panRec.delegate = self
    yourView.addGestureRecognizer(panRec)
    
  4. 同時ジェスチャーを許可する

    func gestureRecognizer(UIGestureRecognizer,
    shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool {
        // println("shouldRecognizeSimultaneouslyWithGestureRecognizer");
        return true
    }
    
    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
         // We only allow the (drag) gesture to continue if it is within a long press
         if((gestureRecognizer is UIPanGestureRecognizer) && (shouldAllowPan == false)) {
             return false;
         }
         return true;
    }
    
  5. 長押しハンドラーの内部:

    func longPress(sender: UILongPressGestureRecognizer) {
    
        if(sender.state == .Began) {
            // handle the long press
        }
        else if(sender.state == .Changed){
            shouldAllowPan = true
    
        }
        else if (sender.state == .Ended) {
            shouldAllowPan = false
        }
    } 
    
于 2015-05-04T14:42:28.673 に答える
1

より多くのジェスチャーを組み合わせるには:

  1. ローカル変数を作成するvar shouldAllowSecondGesture : Bool = false
  2. 2つの認識機能を作成します

let longPressRec = UILongPressGestureRecognizer(target: self, action: #selector(self.startDrag(sender:))) cell.addGestureRecognizer(longPressRec) let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(sender:))) cell.isUserInteractionEnabled = true cell.addGestureRecognizer(panGestureRecognizer)

  1. VCを拡張し、このメソッドを実装するためにGestureRecognizerDelegateを実装します。

    拡張YourViewController:UIGestureRecognizerDelegate {

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
            return true
        }
    
    
    
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
             // We only allow the (drag) gesture to continue if it is within a long press
             if((gestureRecognizer is UIPanGestureRecognizer) && (shouldAllowPan == false)) {
                 return false
             }
             return true
        }
    
    
    @objc func startDrag(sender:UIPanGestureRecognizer) {
    
        if(sender.state == .began) {
                // handle the long press
            }
        else if(sender.state == .changed){
                shouldAllowPan = true
    
            }
            else if (sender.state == .ended) {
                shouldAllowPan = false
            }
        }
    
于 2020-04-04T17:51:38.460 に答える
0

AppleのUIGestureRecognizerクラスリファレンスの「サブクラス化に関する注意事項」セクションをお読みください。

https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UIGestureRecognizer_Class/

于 2016-01-12T05:38:41.710 に答える
0

「アクション:セレクター?」の目的の機能を実装することで、この問題を解決しました。「アクション:セレクター」内のUIPanGestureRecognizerの機能 UILongPressGestureRecognizerの関数。

「UILongPressGestureRecognizer」には「translation」というメンバーがないため、元のタッチの位置を保存し、実際のタッチ位置から抽出して翻訳を計算しました。


// in target class
var initialTouchX : CGFloat
var initialTouchX : CGFloat


// in the @objc func for the UILongPressGestureRecognizer
if sender.state == .began {
   initialTouchX = sender.location(in: sender.view).x
   initialTouchY = sender.location(in: sender.view).y
}

let translation = CGVector(dx: sender.location(in: sender.view).x - initialTouchX, dy: sender.location(in: sender.view).y - initialTouchY)


于 2021-01-12T13:55:46.803 に答える