learning swift and other stuff

resigning keyboard in UITableView

Published May 2020

it is common practice to somehow dismiss the keyboard when you touch outside the field currently receiving keyboard input. The "somehow" is done quite differently. A common solution that can ofentimes be found is to add a GestrureRecognizer to your viewDidLoad:

// for resigning keyboard
let tapGesture = UITapGestureRecognizer(target: self, 
                                        action: #selector(dismissKeyboard(_:)))
self.view.addGestureRecognizer(tapGesture)

At the first glance this seems to be a simple solution. But it has a catch for more complex TableView functions. If you have are UITableViewDelegate and you rely on didSelectRowAtIndexPath your Delegate will no longer receive it because your GestureRecognizer is intercepting the touch and it is not delivered to your delegate.

the Solution is to tell your GestureRecognizer to not consume the touches but also deliver them to the view.

tapGesture.cancelsTouchesInView = false.

so your final code looks like this:

// for resigning keyboard
let tapGesture = UITapGestureRecognizer(target: self, 
                                        action: #selector(dismissKeyboard(_:)))
tapGesture.cancelsTouchesInView = false
self.view.addGestureRecognizer(tapGesture)

Apples documentation

When this property is true (the default) and the receiver recognizes its gesture, the touches of that gesture that are pending are not delivered to the view and previously delivered touches are cancelled through a touchesCancelled(_:with:) message sent to the view. If a gesture recognizer doesn’t recognize its gesture or if the value of this property is false, the view receives all touches in the multi-touch sequence