ios 如何删除手势识别器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10947982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:40:57  来源:igfitidea点击:

How to remove gesture recogniser

iphoneobjective-ciosipadios4

提问by CodeGeek123

SO, I am adding a gesture recogniser to an overlay view. When tapped on screen i want this overlay to go away. Having said that adding a gesture recognizer overrides the "touch up inside" and other button click events. I need this back therefore i need to removegesturerecognizer. I can use this method however i have a problem. My code below -

所以,我正在向叠加视图添加手势识别器。在屏幕上点击时,我希望此叠加层消失。话虽如此,添加手势识别器会覆盖“touch up inside”和其他按钮点击事件。我需要这个回来,因此我需要删除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];    

}

}

Here i am taking the overlay off the other view.

在这里,我将覆盖从另一个视图中移除。

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

My question is how do i remove the gesture recognizer in the second method? I cant pass the variable tap into this method nor can i remove it in the previous method either. Any pointers? Ive been stuck with quite a lot of passing variable problems when it comes to events.

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

采纳答案by E-Riddie

From the WWDC 2015, Cocoa Touch Best Practices, it is suggested that you keep a property or iVar if you need to access it later, and don't go with using viewWithTag:.

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

Moto: Properties instead of Tags

Moto:属性而不是标签

This saves you from some trouble:

这样可以避免一些麻烦:

  1. When dealing with multiple gestures, you remove the gesture that you want directly with accessing the property and remove it. (Without the need to iterate all the view's gestures to get the correct one to be removed)
  2. Finding the correct gesture by the tag when you are iterating, is very misleading when you have multiple tags on views, and when having conflicts with a specific tag
  1. 在处理多个手势时,您可以通过访问属性直接删除所需的手势并将其删除。(无需迭代所有视图的手势即可删除正确的手势)
  2. 当您在迭代时通过标签找到正确的手势,当您在视图上有多个标签时,以及与特定标签发生冲突时,这是非常具有误导性的

(i.e) You implemented it first time with tags, and everything works as expected. Later you work on another functionality which lets say breaks this and causes undesired behavior that you don't expect it. Log doesn't give you a warning, and the best thing you can get depending on the case it's a crash signalizing unrecognized selector sent to instance. Sometimes you won't get any of these.

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

Solution

解决方案

Declare the iVar

声明 iVar

@implementation YourController {
    UITapGestureRecognizer *tap;
}

Setup your view

设置您的视图

- (void) helpClicked {
    //Your customization code

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

Remove the gesture directly

直接去掉手势

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

回答by Omar Abdelhafith

This loop will remove all gesture recognizers a view has

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

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

回答by Rok Jarc

Declare an ivarUITapGestureRecognizer *tapin your @interface.

声明一个ivarUITapGestureRecognizer *tap在你的@interface

Change helpClickedto:

更改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];  
}

and dismissViewto:

dismissView

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

EDIT: i think nhahtdh's method is a bit more elegant compared to this one.

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

EDIT2: it seems you have [self addGestureRecognizer:tap]working so i'm asumming this is a subclass of UIView.

EDIT2:看来你在[self addGestureRecognizer:tap]工作,所以我假设这是UIView.

回答by budidino

Swiftversion:

迅捷版:

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

回答by skram

Your code should probably look more like this, for the second method:

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

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

I added the check for UITapGestureRecognizer, in case your class handles more than 1 UIGestureRecognizers and you only want to remove that.

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

回答by nhahtdh

Just set up the overlay view once, with the gesture recognizer set up, but make the overlay view hidden. When a view is hidden, it won't receive any touch from user. Only make the overlay view visible the view when necessary, and make it hidden when you don't need it.

只需设置一次覆盖视图,并设置手势识别器,但将覆盖视图隐藏。当视图隐藏后,就不会再收到来自用户的任何联系。仅在必要时使叠加视图在视图中可见,并在不需要时将其隐藏。

回答by Matheus Veloza

This work for me:

这对我有用:

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

回答by Fran Pugl

If you are able to extend the view you could try this way:

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

_ = gestureRecognizers.flatMap { 
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
        }
    }
.map { removeGestureRecognizer(
while (view.gestureRecognizers.count) {
  [view removeGestureRecognizer:[view.gestureRecognizers objectAtIndex:0]];
}
) } }

回答by iOS Lifee

In Swift 4

在斯威夫特 4

##代码##

回答by Adeel Ishaq

It worked for me.

它对我有用。

##代码##