【问题标题】:UIGesture failing for unknown reason in IOSUIGesture 在 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 手势的状态。这是第一次“结束”,并且下一次永远不会达到此代码

【问题讨论】:

    标签: iphone ios uiresponder


    【解决方案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];
    

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

    【讨论】:

      猜你喜欢
      • 2020-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-10
      • 2021-09-01
      相关资源
      最近更新 更多