web-dev-qa-db-ja.com

UIGestureRecognizerを複数のビューに添付できますか?

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)];
[self.view1 addGestureRecognizer:tapGesture];
[self.view2 addGestureRecognizer:tapGesture];
[tapGesture release];

上記のコードでは、view2のタップのみが認識されます。 3行目をコメントアウトすると、view1のタップが認識されます。私の言うとおりで、ジェスチャー認識機能を1回しか使用できない場合、これがバグなのか、それともさらにドキュメントが必要なのかわかりません。

218
kubi

UIGestureRecognizerは単一のビューで使用されます。ドキュメンテーションがむらがあることに同意します。 UIGestureRecognizerには単一のviewプロパティがあるため、次のようになります。

表示

ジェスチャ認識エンジンが接続されているビュー。 (読み取り専用)

@property(nonatomic、readonly)UIView * view

ディスカッションaddGestureRecognizer:メソッドを使用して、ジェスチャレコグナイザーをUIViewオブジェクトにアタッチ(または追加)します。

317
TomSwift

以下を使用して回避しました。

for (UIButton *aButton in myButtons) {

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

}

次に、handleLongPressメソッドで、UIButtonをジェスチャレコグナイザのビューに等しく設定し、そのボタンに基づいて実行することを分岐します。

- (void)handleLongPress:(UILongPressGestureRecognizer*)gesture {
    if ( gesture.state == UIGestureRecognizerStateEnded ) {
        UIButton *whichButton=(UIButton *)[gesture view];
        selectedButton=(UIButton *)[gesture view];
    ....
}
48
kwalker

Swift 3の場合、誰かがこれを必要とする場合:上記のBhavik Rathod Answerに基づきます。

 func setGestureRecognizer() -> UIPanGestureRecognizer {

        var panRecognizer = UIPanGestureRecognizer()

        panRecognizer = UIPanGestureRecognizer (target: self, action: #selector(pan(panGesture:)))
        panRecognizer.minimumNumberOfTouches = 1
        panRecognizer.maximumNumberOfTouches = 1
        return panRecognizer
    }

        ///set the recognize in multiple views
        view1.addGestureRecognizer(setGestureRecognizer())
        view2.addGestureRecognizer(setGestureRecognizer())
18
George Asda

いいえ、ジェスチャレコグナイザーを複数のビューに添付しないでください。

Appleドキュメントには、この明示的な情報があります。

ジェスチャ認識機能がビューに添付されます

すべてのジェスチャレコグナイザーは1つのビューに関連付けられます。対照的に、単一のビューが多くの異なるジェスチャに応答する可能性があるため、ビューには複数のジェスチャ認識機能を設定できます。ジェスチャレコグナイザーが特定のビューで発生するタッチを認識するためには、ジェスチャレコグナイザーをそのビューにアタッチする必要があります。

iOSのイベント処理ガイド-ジェスチャレコグナイザー Apple Developer Library

他の人が言及するように、彼らはいくつかのケースで動作する可能性がありますが、明らかにドキュメントに反しており、将来のiOSバージョンで変更される可能性があります。

できることは、監視するビューに個別のジェスチャ認識機能を追加し、共通のアクションを共有できることです。

8
Joseph Lord

このようなことができます、それは簡単でシンプルです

1)コントローラで次のような関数を作成します(この関数はGestureRecognizerを返します)

-(UITapGestureRecognizer*)setRecognizer{
     UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openProfile)];
     [gestureRecognizer setNumberOfTapsRequired:1];
     return gestureRecognizer;
}

2)複数のビューでこの認識エンジンを設定する

[self.view1 addGestureRecognizer:[self setRecognizer]]; 
[self.view2 addGestureRecognizer:[self setRecognizer]];
8
Bhavik Rathod

誰かが kwalker のような複数のボタンのジェスチャービューを追加するためにコーディングしたくなく、Interface Builderでそれをしたい場合、これはあなたを助けるかもしれません。

1)UIButtonやUILabelsなどの他のオブジェクトを追加するように、オブジェクトライブラリから長押しジェスチャー認識機能を追加できます。

enter image description here 最初に使用したのは1つだけでした

2)参照するアウトレットをUIButtonに設定し、ファイルの所有者にアクションを送信します。

enter image description here

注:複数のUIButtonまたは他のオブジェクトがある場合、それぞれに個別のジェスチャー認識機能が必要になります。詳細については、この質問を参照してください。 長押しジェスチャー認識機能で間違ったUIButtonタグを取得する

4
rohan-patel

同じfuncを指すジェスチャレコグナイザーを追加するたびに、GestureRecognizeを再作成(再作成)するのはどうでしょうか。以下の場合、動作します。 IBOutletCollectionを使用しています

スイフト2:

@IBOutlet var topicView: [UIView]!

override func viewDidLoad() {
        for view in self.topicView as [UIView] {
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "viewClicked:"))
    }
}

func viewClicked(recognizer: UITapGestureRecognizer) {
    print("tap")
}
2
febaisi

ビューを固定している場合は、このようなことを行うことをお勧めします

[self.view1 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];
[self.view2 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];

その方法は、複数の異なる無駄な変数を削減します

2

'<UIScrollViewDelegate>'でクラスをオーバーライドします

そして、このメソッドを.mクラスで使用します。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

このメソッドは、単一のビューで複数のスワイプを有効にするのに役立ちます。

2
AnkitRox

ビューに汎用拡張機能を作成して、ジェスチャー認識機能を簡単に追加できます。これは単なる例ですが、次のようになります

extension UIView {

    func setGestureRecognizer<Gesture: UIGestureRecognizer>(of type: Gesture.Type, target: Any, actionSelector: Selector, swipeDirection: UISwipeGestureRecognizer.Direction? = nil, numOfTaps: Int = 1) {
    let getRecognizer = type.init(target: target, action: actionSelector)

    switch getRecognizer {
    case let swipeGesture as UISwipeGestureRecognizer:
        guard let direction = swipeDirection else { return }
        swipeGesture.direction = direction
        self.addGestureRecognizer(swipeGesture)
    case let tapGesture as UITapGestureRecognizer:
        tapGesture.numberOfTapsRequired = numOfTaps
        self.addGestureRecognizer(tapGesture)
    default:
        self.addGestureRecognizer(getRecognizer)
    }
  }

}

呼び出すだけのビューに2タップ認識機能を追加するには:

let actionSelector = #selector(actionToExecute)
view.setGestureRecognizer(of: UITapGestureRecognizer.self, target: self, actionSelector: actionSelector, numOfTaps: 2)

スワイプレコグナイザーを簡単に追加することもできます

view.setGestureRecognizer(of: UISwipeGestureRecognizer.self, target: self, actionSelector: actionSelector, swipeDirection: .down)

等々。ターゲットをセレクターにリンクする必要があることに注意してください。

0
Martin