UIGesture се проваля поради неизвестна причина в IOS

Имам 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. който е "завършен" първия път и всички следващи пъти този код никога не е достигнат


person Nathan    schedule 23.01.2011    source източник


Отговори (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;
}

Ето един примерен проект, демонстриращ този код в употреба.

person mackross    schedule 23.01.2011
comment
Този отговор ми даде указанието, от което се нуждаех, за да разреша собствения си проблем. Имах разпознаване на докосване за изглед, който беше игнориран при докосване на подизгледа на текстовото поле. Като деактивирах временно всички gestureRecognizers в текстовото поле, получих поведението, което търсех, без лоши странични ефекти. - person phatmann; 06.05.2014

Това, което правиш, изглежда наистина странно, но каквото и да е. Предполагам, че знаеш какво правиш.

Може да опитате следното:

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

Това означава, че разпознавателят с едно докосване ще се задейства само ако този с двойно докосване не се задейства, което на практика ги прави взаимно изключващи се.

person Dave DeLong    schedule 23.01.2011