2013-04-04 4 views
48

Мне нужно реализовать функцию, которая будет вызывать некоторый код при двойном нажатии на self.view (вид UIViewCotroller). Но проблема в том, что у меня есть другой объект пользовательского интерфейса в этом представлении, и я не хочу прикреплять к нему всех объектов распознавателя. Я нашел этот метод ниже, как сделать жест на мой взгляд, и я знаю, как он работает. Прямо сейчас я перед гандикапом, который выбирает для создания этого распознавателя, игнорируя subview. Есть идеи? Благодарю.UITapGestureRecognizer tap on self.view, но игнорировать subviews

UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap:)]; 
[doubleTap setNumberOfTapsRequired:2]; 
[self.view addGestureRecognizer:doubleTap]; 
+0

Я не уверен, но вы пробовали настройки cancelsTouchesInView в NO на распознаватель? поэтому [doubleTap setCancelsTouchesInView: NO]; – JDx

ответ

85

Вы должны принять UIGestureRecognizerDelegate протокол внутри self объекта и вызвать метод ниже для проверки зрения. Внутри этого метода проверьте свое мнение против touch.view и верните соответствующий bool (Да/Нет). Что-то вроде этого:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
{ 
    if ([touch.view isDescendantOfView:yourSubView]) { 
     return NO; 
    } 
    return YES; 
} 

Редактировать: Пожалуйста, также проверьте ответ @ Ian!

+0

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

+0

, если у ваших кнопок есть свои распознаватели жестов (вероятно), выкопайте их внутренности и возьмите их, и прочитайте документы на '- [UIGestureRecognizer requireGestureRecognizerToFail:]', но он может работать без изменения их – bshirley

+0

искал это часами ! Благодаря! ;) – MasterRazer

10

И для варианта Swift:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool { 
    if touch.view.isDescendantOfView(yourSubView){ 
     return false 
    } 
    return true 
} 

Хорошо знать, isDescendantOfView возвращает значение, указывающее, Boolean ли приемник подвид данного вида или идентичны с этой точки зрения.

+1

Не забудьте установить UIGestureRecognizerDelegate в своем классе! – Fox5150

+1

Вместо того чтобы делать это утверждение if, вы не можете просто вернуть это? return! Touch.view.isDescendant (of: gestureRecognizer.view) Кроме того, новый синтаксис в swift 3 ^^ – EdwardSanchez

33

Другой подход - просто сравнить, если вид прикосновения - это вид жестов, потому что потомки не пройдут условие. Хороший, простой один вкладыш:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { 
    return touch.view == gestureRecognizer.view 
} 
+1

Это работает лучше для меня, чем принятый ответ. Гораздо более кратким. –

+1

@ Этот метод не вызывается при нажатии на представление. – Prabu

+0

Отличный краткий ответ! – scurioni

5

Полное быстрое решение (делегат должен быть реализован и установить для распознавателя (ов)):

class MyViewController: UIViewController UIGestureRecognizerDelegate { 

    override func viewDidLoad() { 
     let doubleTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(onBaseTapOnly)) 
     doubleTapRecognizer.numberOfTapsRequired = 2 
     doubleTapRecognizer.delegate = self 
     self.view.addGestureRecognizer(doubleTapRecognizer) 
    } 

    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool { 
     if touch.view.isDescendantOfView(self.view){ 
      return false 
     } 
     return true 
    } 

    func onBaseTapOnly(sender: UITapGestureRecognizer) { 
     if sender.state == .Ended { 
      //react to tap 
     } 
    } 
} 
1

Обратите внимание, что gestureRecognizer API изменился на:

gestureRecognizer (_: shouldReceive :)

Обратите внимание на индикатор подчеркивания (пропустить) для внешней метки первого параметра.

Используя многие из приведенных выше примеров, я не получил событие. Ниже приведен пример, который работает для текущих версий Swift (3+).

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { 
    var shouldReceive = false 
    if let clickedView = touch.view { 
     if clickedView == self.view { 
      shouldReceive = true; 
     } 
    } 
    return shouldReceive 
} 
0

Плюс вышеупомянутые решения, не забудьте проверить User Interaction Enabled вашего подвид.

enter image description here

Смежные вопросы