Как удалить распознаватель жестов
SO, я добавляю распознаватель жестов к оверлейному представлению. Когда я нахожусь на экране, я хочу, чтобы этот оверлей ушел. Сказав, что добавление распознавателя жестов отменяет "прикосновение внутрь" и другие события нажатия кнопки. Мне нужно это обратно, поэтому мне нужно removegesturerecognizer. Я могу использовать этот метод, однако у меня проблема. Мой код ниже -
- (void)helpClicked
{
CGRect visibleBounds = [self convertRect:[self bounds] toView:viewContainer];
CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
UIImageView * helpOverlay = [[UIImageView alloc]initWithFrame:CGRectMake(minimumVisibleX, 0, 1024, 768)];
UIImage * helpImage = [UIImage imageNamed:@"HelpOverLay.png"];
[helpOverlay setImage:helpImage];
helpOverlay.tag = 50;
self.scrollEnabled = NO;
[self addSubview:helpOverlay];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
Здесь я беру оверлей с другого вида.
- (void) dismissView
{
UIView *overlay = [self viewWithTag:50];
[overlay removeFromSuperview];
self.scrollEnabled = YES;
}
Мой вопрос: как удалить распознаватель жестов во втором методе? Я не могу передать переменную ссылку на этот метод, и я не могу удалить его в предыдущем методе. Любые указатели? Ive застрял с довольно большим количеством переменных проблем, когда дело доходит до событий.
Ответы
Ответ 1
Из WWDC 2015, Cocoa Touch Best Practices, вам предлагается сохранить свойство или iVar, если вам нужно получить к нему доступ позже, и не используйте с помощью viewWithTag:
.
Moto: свойства вместо тегов
Это избавит вас от некоторых проблем:
- При использовании нескольких жестов вы удаляете жест, который вы хотите получить непосредственно с доступом к свойству, и удалите его. (Без необходимости повторять все жесты представления, чтобы получить правильный, который нужно удалить).
- Поиск правильного жестов с помощью тега при повторении, очень вводит в заблуждение, когда у вас есть несколько тегов для представлений и при конфликтах с определенным тегом
(т.е.) Вы впервые применили теги, и все работает как и ожидалось. Позже вы работаете над другой функциональностью, которая позволяет нарушает это и вызывает нежелательное поведение, которого вы не ожидаете. Журнал не дает вам предупреждения, и самое лучшее, что вы можете получить, в зависимости от случая, когда аварийный сигнал сигнализирует непризнанный селектор, отправленный экземпляру. Иногда вы не получите ни одного из них.
Решение
Объявить iVar
@implementation YourController {
UITapGestureRecognizer *tap;
}
Настройка представления
- (void) helpClicked {
//Your customization code
//Adding tap gesture
tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
Удалить жест напрямую
- (void) dismissView {
[self.view removeGestureRecognizer:tap];
}
Ответ 2
В этом цикле будут удалены все распознаватели жестов, которые имеют вид
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
[self.view removeGestureRecognizer:recognizer];
}
Ответ 3
Объявите ivar
UITapGestureRecognizer *tap
в @interface
.
Измените helpClicked
на:
- (void)helpClicked
{
CGRect visibleBounds = [self convertRect:[self bounds] toView:viewContainer];
CGFloat minimumVisibleX = CGRectGetMinX(visibleBounds);
UIImageView * helpOverlay = [[UIImageView alloc]initWithFrame:CGRectMake(minimumVisibleX, 0, 1024, 768)];
UIImage * helpImage = [UIImage imageNamed:@"HelpOverLay.png"];
[helpOverlay setImage:helpImage];
helpOverlay.tag = 50;
self.scrollEnabled = NO;
[self addSubview:helpOverlay];
tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissView)];
[self addGestureRecognizer:tap];
}
и dismissView
:
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
[self removeGestureRecognizer:tap];
}
EDIT: я думаю, что метод nhahtdh немного более изящный по сравнению с этим.
EDIT2: кажется, что у вас есть [self addGestureRecognizer:tap]
, работающий, поэтому я asumming это подкласс UIView
.
Ответ 4
Просто настройте представление наложения один раз, с помощью распознавателя жестов настройте, но сделайте оверлейный вид скрытым. Когда вид скрыт, он не получит никакого касания от пользователя. Только сделайте вид наложения видимым, когда это необходимо, и сделайте его скрытым, когда он вам не понадобится.
Ответ 5
Ваш код должен, вероятно, больше похож на этот, для второго метода:
- (void) dismissView {
UIView *overlay = [self viewWithTag:50];
for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
if([recognizer isKindOfClass:[UITapGestureRecognizer class]]) {
[self removeGestureRecognizer:recognizer];
}
}
[overlay removeFromSuperview];
self.scrollEnabled = YES;
}
Я добавил проверку для UITapGestureRecognizer
, если ваш класс обрабатывает более 1 UIGestureRecognizer
, и вы хотите удалить его.
Ответ 6
Эта работа для меня:
for (UIGestureRecognizer *gr in self.view.gestureRecognizers) {
[self.view removeGestureRecognizer:gr];
}
Ответ 7
версия Swift:
for recognizer in yourView.gestureRecognizers! {
yourView.removeGestureRecognizer(recognizer)
}
Ответ 8
Это сработало для меня.
while (view.gestureRecognizers.count) {
[view removeGestureRecognizer:[view.gestureRecognizers objectAtIndex:0]];
}
Ответ 9
Если вы можете расширить представление, вы можете попробовать таким образом:
_ = gestureRecognizers.flatMap { $0.map { removeGestureRecognizer($0) } }