Добавление нескольких UITapGestureRecognizer в одно представление (Cocos2d)

Я добавляю следующий код в метод onEnter.

doubleTapRecognizer_ = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)];
    doubleTapRecognizer_.numberOfTapsRequired = 2;
    doubleTapRecognizer_.cancelsTouchesInView = NO;
    [[[CCDirector sharedDirector] view] addGestureRecognizer:doubleTapRecognizer_];

У меня есть несколько экземпляров этого класса, но единственный, который вызывает его селектор, - это последний добавленный экземпляр. справочник по классам UIView заставляет меня поверить, что можно добавить более одного UIGestureRecognizer в одно представление. Свойство «gestureRecognizers» возвращает NSArray.

На самом деле у меня уже есть UIPanGestureRecognizer, работающий с тем же представлением из другого класса. Поэтому я получаю как минимум два UIGestureRecognizers для работы одновременно.


person Joshua Goossen    schedule 07.07.2012    source источник


Ответы (2)


Вы можете добавить несколько распознавателей жестов в одно и то же представление. Чего вы не можете (легко) сделать, так это добавить несколько экземпляров одного и того же типа распознавателя жестов (панорамирование, пролистывание, двойное нажатие и т. д.) в одно и то же представление.

Почему?

Потому что, как только первый распознаватель жестов распознает жест (в данном случае двойное касание), он отменяет все события касания. Поэтому оставшиеся распознаватели жестов никогда не завершат распознавание и никогда не запустят свои события.

Вам не нужно более одного распознавателя жестов одного типа. В вашем случае, как только вы получили событие двойного нажатия, вы должны сигнализировать правильному объекту о том, что он был двойным нажатием. Используйте положение распознавателя и другие атрибуты, чтобы найти, например, спрайт, по которому дважды коснулись, а затем заставить его делать то, что нужно.

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

person LearnCocos2D    schedule 08.07.2012
comment
Ваше решение звучит великолепно и его будет легко реализовать, но ради изучения смысла doubleTapRecognizer_.cancelsTouchesInView = NO; Разве это не должно отключить отмену касания? - person Joshua Goossen; 08.07.2012

Чтобы добавить более одного UIGestureRecognizer в одно и то же представление, вам необходимо установить свойство delegate распознавателей жестов, которые вы добавили в представление, и реализовать следующий метод в делегате:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

Как указано выше, вы можете добавить несколько распознавателей жестов в одно и то же представление, независимо от того, относятся ли распознаватели жестов к одному типу или нет.

Например, вы можете добавить два UITapGestureRecognizer в одно и то же представление, и будут вызываться обратные вызовы двух распознавателей жестов касания. И последний добавленный обратный вызов будет вызван первым.

Надеюсь это поможет.

person HongchaoZhang    schedule 06.03.2017
comment
Иногда нам действительно нужно добавить второй распознаватель жестов того же типа к уже существующему распознавателю жестов. Например, для MKMapView на нем уже есть жест сжатия, и я хочу делать некоторые другие вещи, когда я масштабирую карту, выполняя жест сжатия. В этом случае мне нужно добавить еще один распознаватель жестов щипка к MKMapView и одновременно заставить работать существующий распознаватель жестов щипка. - person HongchaoZhang; 06.03.2017
comment
Спасибо за это! Я согласен с @HongchaoZhang, что существует вариант использования, когда простой вызов функции из другого метода не помогает. - person Anters Bear; 05.07.2018