2011-01-23 3 views
3

У меня есть UITextField, который является подзадачей UIScrollView У меня есть единственный жест нажатия (или, возможно, более старый контакт) как часть UITextField, который делает его первым ответчиком. Я хотел добавить двойной жест Жест к UITextField. Чтобы сделать два Gesture взаимоисключающими, мне нужно было перегрузить (хотя это не совсем то слово, потому что я не использую одно и то же имя) единственное нажатие Gesture. Когда я это делаю, это прекрасно работает, пока функция, которую он вызывает, не делает UITextField первым ответчиком. Если это делает текстовое поле первым ответчиком, он не работает во второй раз, когда он называется ... wtf. Так что стопка, небольшая помощь проделана долгий путь.Ошибка UIGesture по неизвестной причине в IOS

это где я добавить этот жест

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, что из ставит gestuers зарегистрированных в TextField это было проверить состояние моего жестов singleTextTap. который «закончился» в первый раз, и все следующие раз этот код никогда не был достигнут

ответ

2

Поведение, которое вы видите, связано с тем, что каждый раз, когда вы отправляете сообщение becomeFirstResponder на UITextField, он устанавливает свои собственные распознаватели жестов. Если вы выполните вход в [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 демонстрирует этот код в использовании.

+1

Этот ответ дал мне ключ, который мне нужен, чтобы решить мою собственную проблему. У меня был распознаватель крана для представления, которое было проигнорировано при нажатии на подзаголовок текстового поля. Временно отключив все «gestureRecognizers» в текстовом поле, я получил поведение, которое искал, без каких-либо побочных эффектов. – phatmann

1

То, что вы делаете, кажется действительно странным, но что угодно. Предполагаю, вы знаете, что делаете.

Вы можете попробовать следующее:

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

Это означает, что одним нажатием распознаватель будет стрелять только если двойное нажатие один не срабатывает, эффективно делая их взаимоисключающими.