Подтвердить что ты не робот

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

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 застрял с довольно большим количеством переменных проблем, когда дело доходит до событий.

4b9b3361

Ответ 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) } }