3

我有一个 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];
}

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

4

2 回答 2

2

The behaviour you're seeing is due to each time you send a becomeFirstResponder message to a UITextField it sets it's own gesture recognizers up. If you do a log on [textField gestureRecognizers] you'll see it sets up a lot of them. These are to deal with text editing functions such as long press for cursor movement and such. By way of adding these it cancels the ones you have setup. Easiest way to deal with this is something like this.

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

Here is an example project demonstrating this code in use.

于 2011-01-23T04:38:02.293 回答
1

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

您可以尝试以下方法:

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

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

于 2011-01-23T04:20:15.603 回答