50

所以,我在覆盖视图中添加了一个手势识别器。当点击屏幕时,我希望这个覆盖消失。话虽如此,添加手势识别器会覆盖“内部修饰”和其他按钮单击事件。我需要这个,因此我需要删除gesturerecognizer。我可以使用这种方法,但是我有问题。我的代码如下 -

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

我的问题是如何在第二种方法中删除手势识别器?我不能将变量 tap 传递给这个方法,也不能在以前的方法中删除它。任何指针?在事件方面,我遇到了很多传递变量问题。

4

10 回答 10

108

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

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

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,如果您以后需要访问它,不要使用 using 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];
}
于 2015-07-30T17:38:25.653 回答
7

斯威夫特版本:

if let recognizers = yourView.gestureRecognizers { 
  for recognizer in recognizers {
    yourView.removeGestureRecognizer(recognizer)
  }
}
于 2017-01-20T04:38:47.347 回答
5

只需设置一次覆盖视图,并设置手势识别器,但将覆盖视图隐藏。当视图被隐藏时,它不会收到用户的任何触摸。仅在必要时使覆盖视图可见,并在不需要时将其隐藏。

于 2012-06-08T11:36:04.573 回答
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;
}

我添加了对 的检查UITapGestureRecognizer,以防您的班级处理超过 1UIGestureRecognizer秒并且您只想删除它。

于 2012-06-08T12:44:27.157 回答
3

这对我有用:

for (UIGestureRecognizer *gr in self.view.gestureRecognizers) {
  [self.view removeGestureRecognizer:gr];
}
于 2014-12-01T12:54:39.840 回答
2

在斯威夫特 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
        }
    }
于 2018-06-27T06:14:19.640 回答
1

如果您能够扩展视图,您可以尝试这种方式:

_ = gestureRecognizers.flatMap { $0.map { removeGestureRecognizer($0) } }
于 2017-10-11T14:42:41.750 回答
0

它对我有用。

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