Почему UIGestureRecognizer вызывается на мою кнопку очистки текстового поля?
У меня есть UITableView с добавлением распознавателя жестов:
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[myTableView addGestureRecognizer:gestureRecognizer];
gestureRecognizer.cancelsTouchesInView = NO;
... все работает нормально, когда вы нажимаете на таблицу, чтобы закрыть клавиатуру. Моя проблема заключается в том, что мой метод hideKeyboard также вызывает, когда вы нажимаете кнопку "clear" на моем UITextField. Очень странно.
commentTextField = [[UITextField alloc] initWithFrame:CGRectMake(5, 5, 310, 35)];
commentTextField.contentVerticalAlignment =UIControlContentVerticalAlignmentCenter;
commentTextField.borderStyle = UITextBorderStyleRoundedRect;
commentTextField.textColor = [UIColor blackColor]; //text color
commentTextField.font = [UIFont fontWithName:@"Helvetica" size:14.0]; //font size
commentTextField.placeholder = @"Enter a comment..."; //place holder
commentTextField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
commentTextField.keyboardType = UIKeyboardTypeDefault; // type of the keyboard
commentTextField.returnKeyType = UIReturnKeySend; // type of the return key
commentTextField.clearButtonMode = UITextFieldViewModeAlways; // has a clear 'x' button to the right
commentTextField.delegate = self;
[commentTextField setHidden:NO];
[commentTextField setEnabled:YES];
[commentTextField setDelegate: self];
hide keyboard method:
- (void) hideKeyboard{
if(keyboard){
[commentTextField resignFirstResponder];
[UIView animateWithDuration:.3
delay:.0
options:UIViewAnimationCurveEaseInOut
animations:^{ // start animation block
[myTableView setFrame:CGRectMake(0, myTableView.frame.origin.y + 216, myTableView.frame.size.width, myTableView.frame.size.height)];
}
completion:^(BOOL finished){
}];
keyboard = 0;
}
}
Любая помощь будет оценена, спасибо!
Ответы
Ответ 1
Ниже приведено несколько более общее - оно не связано с вашими конкретными видами:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UITextField class]] ||
[touch.view isKindOfClass:[UIButton class]])
{
return NO;
}
return YES;
}
Кроме того, не забудьте указать делегат для распознавателя жестов и пометить класс как реализацию протокола UIGestureRecognizerDelegate.
Ответ 2
У меня была такая же проблема. На мой взгляд, я также использовал следующий метод:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ((touch.view == self.textField) && (gestureRecognizer == self.tapGestureRecognizer))
{
return NO;
}
return YES;
}
Но это все еще не сработало. Поэтому я установил перерыв в методе и увидел, что когда я нажму на поле, touch.view будет настроен на него, но когда я нажал на кнопку очистки, он появился как UIButton *. В этот момент было очевидно, что происходит и что делать, чтобы исправить это. Ниже решается проблема.
if((touch.view == self.textField || [self.textField.subviews containsObject:touch.view]) && (gestureRecognizer == self.tapGestureRecognizer))
{
return NO;
}
Ответ 3
Моя проблема с подходом Ezmodius заключается в том, что он зависит от свойства, называемого textField, а мой UIViewController - это контроллер, из которого наследуются все мои другие UIViewControllers, поэтому мне нужно было реализовать более общий подход: всякий раз, когда в текстовом поле любой UIViewController, который нужно очистить, я реализовал следующее (внутри одного и того же метода распознавания:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UITextField class]] ||
([touch.view isKindOfClass:[UIButton class]] && [touch.view.superview isKindOfClass:[UITextField class]]))
{
return NO;
}
return YES;
}
Таким образом, в основном я проверяю, является ли это текстовым полем или кнопкой, чей супервизор является текстовым полем (в данном случае - кнопкой очистки внутри текстового поля), и это работает как прелесть для меня. Я реализовал это в своем базовом классе UIViewController и работает для каждой страницы, где это происходит.