1

I'm implementing a search controller with a search bar on top and a tableview below which displays the results of the search. I added the following code so that when a user taps on the screen, the keyboard will be dismissed.

override func viewDidLoad() {
    super.viewDidLoad()
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
    self.view.addGestureRecognizer(tapGesture)
}

@objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    if let view = self.view {
        view.endEditing(true)
    }
}

However, now when I try to implement the didSelectRowAt method of the table view, it doesn't work as the UITapGestureRecognizer defined in the code above captures the touch event. Ideally, I'd like the tableview touches to take precedence over the code above, so that when a user touches the tableView, didSelectRowAt is called, but when he touches anywhere else on screen, dismissKeyboard is called instead.

Alk
  • 5,215
  • 8
  • 47
  • 116
  • 1
    Does this answer your question? [ScrollView gesture recognizer eating all touch events](https://stackoverflow.com/questions/16882737/scrollview-gesture-recognizer-eating-all-touch-events) – aasatt Jan 14 '20 at 23:24
  • yes it does - thank you – Alk Jan 14 '20 at 23:28

1 Answers1

2

Implement UIGestureRecognizerDelegate and use return false if the touch is on your tableView.

override func viewDidLoad() {
    super.viewDidLoad()
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))

    tabGesture.delegate = self

    self.view.addGestureRecognizer(tapGesture)
}

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

That should solve your problem

Ahmad F
  • 30,560
  • 17
  • 97
  • 143
Eloy B.
  • 565
  • 4
  • 13