I have a UITextField that is the subview of UIScrollView I have there exist a single tap gesture (or perhaps the older touch) as part of UITextField that makes it the first responder. I wanted to add a double tap Gesture to the UITextField. In order to make the two Gesture's mutually exclusive I needed to overload (though this is not quite the right word because I'm not using the same name) the single tap Gesture. When I do it works fine so long as the function that it calls doesn't make the UITextField the first responder. If it does make the textfield the first responder it fails the second time it's called.... wtf. So stack, a little help would go a long way.
this is where I add the gesture
UITapGestureRecognizer * singleTextTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSingleTextTap:)];
singleTextTap.numberOfTapsRequired = 1;
[aTextField addGestureRecognizer:singleTextTap];
and this is where it is called
//single tap text
- (void) handleSingleTextTap:(UITapGestureRecognizer *)gestureRecognizer{
NSLog(@"handling single tap");
NSLog(@"textField gestures %@",
[gestureRecognizer.view.gestureRecognizers descriptionWithLocale:nil]);
[(UITextField *)gestureRecognizer.view becomeFirstResponder];
}
you may notice the NSLog that out puts the gestuers registered to the textField this was to check the state of my singleTextTap gesture. which is 'ended' the first time and al开发者_运维技巧l next times this code is never reached
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.
What you're doing seems really strange, but whatever. I'll assume you know what you're doing.
You might try the following:
UITapGestureRecognizer *doubleTap = ...;
UITapGestureRecognizer *singleTap = ...;
[singleTap requireGestureRecognizerToFail:doubleTap];
This means that the single tap recognizer will only fire if the double tap one doesn't fire, effectively making them mutually exclusive.
精彩评论