50

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 番目の方法でジェスチャ認識エンジンを削除するにはどうすればよいですか? 変数タップをこのメソッドに渡すことも、前のメソッドで削除することもできません。ポインタはありますか?イベントに関しては、非常に多くの変数の問題に悩まされてきました。

4

10 に答える 10

108

このループは、ビューにあるすべてのジェスチャ レコグナイザーを削除します

for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
    [self.view removeGestureRecognizer:recognizer];
}
于 2012-06-08T11:35:20.313 に答える
30

でan を宣言ivar UITapGestureRecognizer *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ます。

于 2012-06-08T11:37:29.840 に答える
30

WWDC 2015 の Cocoa Touch Best Practicesによると、後でアクセスする必要がある場合は、プロパティまたは iVar を保持し、 を使用しないことをお勧めしますviewWithTag:

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

これにより、いくつかの問題を回避できます。

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

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

解決

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];
}
于 2015-07-30T17:38:25.653 に答える
5

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;
}

UITapGestureRecognizerクラスが 1 つ以上UIGestureRecognizerの s を処理し、それのみを削除したい場合に備えて、のチェックを追加しました。

于 2012-06-08T12:44:27.157 に答える
5

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

于 2012-06-08T11:36:04.573 に答える
0

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

while (view.gestureRecognizers.count) {
  [view removeGestureRecognizer:[view.gestureRecognizers objectAtIndex:0]];
}
于 2016-05-07T20:23:40.530 に答える