如何删除手势识别器

Cod*_*123 48 iphone objective-c ipad ios4 ios

所以,我正在为叠加视图添加手势识别器.当点击屏幕时,我希望这个叠加层消失.已经说过添加手势识别器会覆盖"内部触摸"和其他按钮点击事件.我需要这个,因此我需要removegesturerecognizer.我可以使用这种方法,但我有一个问题.我的代码如下 -

- (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];    
Run Code Online (Sandbox Code Playgroud)

}

在这里,我从其他视图中取出叠加层.

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

我的问题是如何在第二种方法中删除手势识别器?我不能将变量tap传递给这个方法,也不能在之前的方法中删除它.有什么指针吗?在涉及到事件时,我一直困扰着相当多的传递变量问题.

Oma*_*ith 106

此循环将删除视图具有的所有手势识别器

for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
    [self.view removeGestureRecognizer:recognizer];
}
Run Code Online (Sandbox Code Playgroud)

  • 正确的答案,不需要使用var来保留手势... tks (3认同)

E-R*_*die 30

WWDC 2015,Cocoa Touch最佳实践,如果您以后需要访问它,建议您保留一个属性或iVar,并且不要继续使用viewWithTag:.

Moto:属性而不是Tags

这样可以省去一些麻烦:

  1. 处理多个手势时,您可以直接删除所需的手势并删除它.(无需迭代所有视图的手势以获取正确的手势)
  2. 在迭代时通过标记查找正确的手势,如果在视图上有多个标记,并且与特定标记发生冲突,则会产生误导

(即)您第一次使用标签实现它,一切都按预期工作.稍后你会处理另一个功能,让我们打破这个功能并导致你不期望的不良行为.Log不会给你一个警告,你可以得到最好的东西,这取决于发送到实例的崩溃信号无法识别的选择器.有时你不会得到任何这些.

声明iVar

@implementation YourController {
    UITapGestureRecognizer *tap;
}
Run Code Online (Sandbox Code Playgroud)

设置您的视图

- (void) helpClicked {
    //Your customization code

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

直接删除手势

- (void) dismissView {
    [self.view removeGestureRecognizer:tap];
}
Run Code Online (Sandbox Code Playgroud)


Rok*_*arc 29

申报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];  
}
Run Code Online (Sandbox Code Playgroud)

dismissView:

for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
    [self removeGestureRecognizer:tap];
}
Run Code Online (Sandbox Code Playgroud)

编辑:我认为nhahtdh的方法比这个方法更优雅.

编辑2:看起来你有[self addGestureRecognizer:tap]工作,所以我认为这是一个子类UIView.


nha*_*tdh 5

只需设置叠加视图一次,设置手势识别器,但隐藏叠加视图.隐藏视图时,不会从用户接收任何触摸.仅在必要时使叠加视图对视图可见,并在不需要时将其隐藏.


skr*_*ram 5

对于第二种方法,您的代码应该看起来更像这样:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

我添加了的检查UITapGestureRecognizer,以防您的类处理超过1 UIGestureRecognizers并且您只想删除它。


bud*_*ino 5

Swift版本:

if let recognizers = yourView.gestureRecognizers { 
  for recognizer in recognizers {
    yourView.removeGestureRecognizer(recognizer)
  }
}
Run Code Online (Sandbox Code Playgroud)