UIGesture 在 IOS 中因未知原因失败

Posted

技术标签:

【中文标题】UIGesture 在 IOS 中因未知原因失败【英文标题】:UIGesture failing for unknown reason in IOS 【发布时间】:2011-01-23 04:06:41 【问题描述】:

我有一个 UITextField,它是 UIScrollView 的子视图 作为 UITextField 的一部分,我有一个单击手势(或者可能是较旧的触摸),使其成为第一响应者。我想向 UITextField 添加双击手势。为了使两个手势互斥,我需要重载单击手势(尽管这不是正确的词,因为我没有使用相同的名称)。当我这样做时,只要它调用的函数不会使 UITextField 成为第一响应者,它就可以正常工作。如果它确实使文本字段成为第一响应者,它第二次被调用时失败.... wtf。所以堆栈,一点帮助会有很长的路要走。

这是我添加手势的地方

 UITapGestureRecognizer * singleTextTap = [[UITapGestureRecognizer alloc] 
             initWithTarget:self action:@selector(handleSingleTextTap:)];         
 singleTextTap.numberOfTapsRequired = 1;
 [aTextField addGestureRecognizer:singleTextTap];

这就是它的名字

//single tap text
- (void) handleSingleTextTap:(UITapGestureRecognizer *)gestureRecognizer
    NSLog(@"handling single tap");
    NSLog(@"textField gestures %@", 
          [gestureRecognizer.view.gestureRecognizers descriptionWithLocale:nil]);
    [(UITextField *)gestureRecognizer.view becomeFirstResponder];

您可能会注意到 NSLog 输出将注册到 textField 的手势这是为了检查我的 singleTextTap 手势的状态。这是第一次“结束”,并且下一次永远不会达到此代码

【问题讨论】:

【参考方案1】:

您看到的行为是由于每次您向UITextField 发送becomeFirstResponder 消息时,它都会设置自己的手势识别器。如果您在 [textField gestureRecognizers] 上进行登录,您会看到它设置了很多。这些用于处理文本编辑功能,例如长按光标移动等。通过添加这些,它会取消您已设置的那些。处理这个问题的最简单方法是这样的。

- (void) singleTap:(UITapGestureRecognizer*)singleTap 
    if (![self.textField isFirstResponder]) 
        [self.textField becomeFirstResponder];
        self.label.text = @"Single Tap -> Make First Responder";
        [self.label setNeedsDisplay];
    

- (void) doubleTap:(UITapGestureRecognizer*)doubleTap 
    if (![self.textField isFirstResponder]) 
        [self.textField becomeFirstResponder];
        self.label.text = @"Double Tap -> Make First Responder";
        [self.label setNeedsDisplay];
    


- (void) setupTextGestureRecognizers 
    for (UIGestureRecognizer *rec in self.textField.gestureRecognizers) 
        [self.textField removeGestureRecognizer:rec];
    
    UITapGestureRecognizer *singleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)] autorelease];
    UITapGestureRecognizer *doubleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)] autorelease];
    [singleTap setNumberOfTapsRequired:1];
    [doubleTap setNumberOfTapsRequired:2];
    [singleTap setCancelsTouchesInView:YES];
    [doubleTap setCancelsTouchesInView:YES];
    [singleTap requireGestureRecognizerToFail:doubleTap];
    [self.textField addGestureRecognizer:singleTap];
    [self.textField addGestureRecognizer:doubleTap];


- (void)viewDidLoad 
    [super viewDidLoad];
    [self setupTextGestureRecognizers];
    self.textField.delegate = self;



- (BOOL) textFieldShouldReturn:(UITextField *)tf 
    [tf resignFirstResponder];
    if (tf == self.textField) 
        [self setupTextGestureRecognizers];
    
    return YES;

这是一个example project 演示此代码的使用。

【讨论】:

这个答案给了我解决我自己的问题所需的线索。我有一个点击识别器,用于点击文本字段子视图时被忽略的视图。通过暂时禁用文本字段中的所有gestureRecognizers,我得到了我正在寻找的行为,没有不良副作用。【参考方案2】:

你在做什么看起来很奇怪,但无论如何。我假设你知道自己在做什么。

您可以尝试以下方法:

UITapGestureRecognizer *doubleTap = ...;
UITapGestureRecognizer *singleTap = ...;
[singleTap requireGestureRecognizerToFail:doubleTap];

这意味着单击识别器只会在双击识别器不触发时触发,从而有效地使它们相互排斥。

【讨论】:

以上是关于UIGesture 在 IOS 中因未知原因失败的主要内容,如果未能解决你的问题,请参考以下文章

Flutter ios 构建失败 - Distill 因未知原因而失败

未知usb设备(设备描述符请求失败)怎么解决?

HttpClient 在 Android 5.0 Lollipop 中因握手失败而失败

命令 CodeSign 在 Xcode 11.3 中因非零退出代码而失败

(未知 url)的 Http 失败响应:android 上的 0 未知错误

dotnet-dump 在 Ubuntu 中因“写入转储失败(HRESULT:0x80004005)”而失败