web-dev-qa-db-ja.com

ジェスチャ認識機能を削除する方法

SO、ジェスチャー認識機能をオーバーレイビューに追加しています。画面をタップすると、このオーバーレイが消えます。ジェスチャレコグナイザーを追加すると、「内部修正」およびその他のボタンクリックイベントがオーバーライドされると述べました。私はこれを必要とするので、ジェスチャ認識を削除する必要があります。この方法は使用できますが、問題があります。以下の私のコード-

- (void)helpClicked
{
    CGRect visibleBounds = [self convertRect:[self bounds] toView:viewContainer];
    CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
    UIImageView * helpOverlay = [[UIImageView alloc]initWithFrame:CGRectMake(minimumVisibleX, 0, 1024, 768)];
    UIImage * helpImage = [UIImage imageNamed:@"HelpOverLay.png"];
    [helpOverlay setImage:helpImage];
    helpOverlay.tag = 50;
    self.scrollEnabled = NO;
    [self addSubview:helpOverlay]; 
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] 
                               initWithTarget:self
                               action:@selector(dismissView)];

[self addGestureRecognizer:tap];    

}

ここで、他のビューからオーバーレイを取ります。

- (void) dismissView
{
    UIView *overlay = [self viewWithTag:50];
    [overlay removeFromSuperview];
    self.scrollEnabled = YES;
}

私の質問は、2番目の方法でジェスチャー認識機能を削除するにはどうすればよいですか?変数tapをこのメソッドに渡すことも、前のメソッドで変数tapを削除することもできません。ポインタはありますか?私は、イベントに関しては非常に多くの通過変数の問題に悩まされてきました。

48
CodeGeek123

WWDC 2015、Cocoa Touch Best Practices から、後でアクセスする必要がある場合はプロパティまたはiVarを保持し、viewWithTag:

Moto:タグではなくプロパティ

これにより、トラブルからあなたを救います:

  1. 複数のジェスチャを処理する場合、プロパティへのアクセスで必要なジェスチャを直接削除して削除します。 (削除する正しいジェスチャを取得するために、ビューのすべてのジェスチャを繰り返す必要なしに)
  2. 繰り返し中にタグによって正しいジェスチャーを見つけることは、ビューに複数のタグがある場合、および特定のタグと競合する場合に非常に誤解を招く可能性があります

(つまり)タグで初めて実装しましたが、すべてが期待どおりに機能します。後で、別の機能に取り組みます。これにより、これを破り、予期しない望ましくない動作を引き起こすことができます。ログは警告を表示しませんが、場合によってはインスタンスに送信されるクラッシュシグナル認識されないセレクターに応じて取得できる最良のものこれらのいずれも取得できない場合があります

溶液

IVarを宣言する

@implementation YourController {
    UITapGestureRecognizer *tap;
}

ビューを設定する

- (void) helpClicked {
    //Your customization code

    //Adding tap gesture
    tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissView)];
    [self addGestureRecognizer:tap];
}

ジェスチャーを直接削除する

- (void) dismissView {
    [self.view removeGestureRecognizer:tap];
}
29
E-Riddie

このループは、ビューにあるすべてのジェスチャー認識機能を削除します

for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
    [self.view removeGestureRecognizer:recognizer];
}
106

ivarUITapGestureRecognizer *tapあなたの@interface

helpClickedを次のように変更します。

- (void)helpClicked
{
    CGRect visibleBounds = [self convertRect:[self bounds] toView:viewContainer];
    CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
    UIImageView * helpOverlay = [[UIImageView alloc]initWithFrame:CGRectMake(minimumVisibleX, 0, 1024, 768)];
    UIImage * helpImage = [UIImage imageNamed:@"HelpOverLay.png"];
    [helpOverlay setImage:helpImage];
    helpOverlay.tag = 50;
    self.scrollEnabled = NO;
    [self addSubview:helpOverlay]; 
    tap = [[UITapGestureRecognizer alloc] 
                               initWithTarget:self
                               action:@selector(dismissView)];

    [self addGestureRecognizer:tap];  
}

およびdismissViewへ:

for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
    [self removeGestureRecognizer:tap];
}

編集:nhahtdhの方法はこれに比べて少しエレガントだと思います。

EDIT2:[self addGestureRecognizer:tap]動作しているので、これはUIViewのサブクラスであると想定しています。

29
Rok Jarc

Swiftバージョン:

if let recognizers = yourView.gestureRecognizers { 
  for recognizer in recognizers {
    yourView.removeGestureRecognizer(recognizer)
  }
}
5
budidino

ジェスチャレコグナイザをセットアップして、オーバーレイビューを一度セットアップするだけで、オーバーレイビューをhiddenにします。ビューが非表示の場合、ユーザーからのタッチは一切受けません。オーバーレイビューを必要な場合にのみ表示し、必要でない場合は非表示にします。

5
nhahtdh

2番目の方法では、コードはおそらく次のようになります。

- (void) dismissView {
  UIView *overlay = [self viewWithTag:50];

  for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
    if([recognizer isKindOfClass:[UITapGestureRecognizer class]]) {
      [self removeGestureRecognizer:recognizer];
    }
  }

  [overlay removeFromSuperview];
  self.scrollEnabled = YES;
}

クラスが複数のUITapGestureRecognizersを処理し、それだけを削除したい場合に備えて、UIGestureRecognizerのチェックを追加しました。

5
skram

私のためのこの仕事:

for (UIGestureRecognizer *gr in self.view.gestureRecognizers) {
  [self.view removeGestureRecognizer:gr];
}
3
Matheus Veloza

In Swift 4

if let gestures = shotButton.gestureRecognizers //first be safe if gestures are there
    {
        for gesture in gestures //get one by one
        {
            shotButton.removeGestureRecognizer(gesture) //remove gesture one by one
        }
    }
1
iOS Lifee

ビューを拡張できる場合は、次の方法を試すことができます。

_ = gestureRecognizers.flatMap { $0.map { removeGestureRecognizer($0) } }
1
Fran Pugl

それは私のために働いた。

while (view.gestureRecognizers.count) {
  [view removeGestureRecognizer:[view.gestureRecognizers objectAtIndex:0]];
}
0
Adeel Ishaq