it-roy-ru.com

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

Итак, я добавляю распознаватель жестов в представление наложения. При нажатии на экран я хочу, чтобы это наложение исчезло. Сказав, что добавление распознавателя жестов отменяет «подправить внутри» и другие события нажатия кнопки. Мне нужно это обратно, поэтому мне нужно удалить распознаватель. Я могу использовать этот метод, однако у меня есть проблема. Мой код ниже - 

- (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;
}

У меня вопрос, как мне удалить распознаватель жестов во втором методе? Я не могу передать переменную tap в этот метод и не могу удалить ее в предыдущем методе. Есть указатели? Я застрял с довольно многими переменными проблемами, когда дело доходит до событий.

48
CodeGeek123

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

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

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

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

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

Решение

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

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

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

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

Правка: я думаю, что метод nhahtdh немного более элегантный по сравнению с этим.

EDIT2: кажется, у вас работает [self addGestureRecognizer:tap], поэтому я полагаю, что это подкласс UIView.

29
Rok Jarc

Swift версия:

if let recognizers = yourView.gestureRecognizers { 
  for recognizer in recognizers {
    yourView.removeGestureRecognizer(recognizer)
  }
}
5
budidino

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

5
nhahtdh

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

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

4
skram

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

for (UIGestureRecognizer *gr in self.view.gestureRecognizers) {
  [self.view removeGestureRecognizer:gr];
}
3
Matheus Veloza

В 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
        }
    }
1
iOS Lifee

Если вы можете расширить представление, вы можете попробовать это следующим образом:

_ = gestureRecognizers.flatMap { $0.map { removeGestureRecognizer($0) } }
1
Fran Pugl

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

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