iphone - Как удалить распознаватель жестов



objective-c ios (7)

В этом цикле будут удалены все распознаватели жестов, которые

for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers) {
    [self.view removeGestureRecognizer:recognizer];
}

Итак, я добавляю распознаватель жестов к оверлейному представлению. Когда я нахожусь на экране, я хочу, чтобы этот оверлей ушел. Сказав, что добавление распознавателя жестов отменяет «прикосновение внутрь» и другие события нажатия кнопки. Мне нужно это обратно, поэтому мне нужно 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;
}

Мой вопрос: как удалить распознаватель жестов во втором методе? Я не могу передать переменную ссылку на этот метод, и я не могу удалить его в предыдущем методе. Любые указатели? Я был застрял с довольно большим количеством переменных проблем, когда дело доходило до событий.


Answer #1

Вероятно, ваш код должен выглядеть более похожим на второй метод:

- (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 и вы хотите его удалить.


Answer #2

Начиная с WWDC 2015, Best Practices Cocoa Touch , вам предлагается сохранить свойство или iVar, если вам нужно получить к нему доступ позже, и не используйте с помощью viewWithTag:

Moto: свойства вместо тегов

Это избавит вас от некоторых неприятностей:

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

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

Решение

Объявить 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];
}

Answer #3

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


Answer #4

Это сработало для меня.

while (view.gestureRecognizers.count) {
  [view removeGestureRecognizer:[view.gestureRecognizers objectAtIndex:0]];
}

Answer #5

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 .


Answer #6

В Swift 4

if let gestures = shotButton.gestureRecognizers //first be safe if gestures are there
    {
        for gesture in gestures //get one by one
        {
            shotButton.removeGestureRecognizer(gesture) //remove gesture one by one
        }
    }




ios4