Dismiss keyboard by touching background of UITableView

Viewed 91081

I have a UITableView with UITextFields as cells. I would like to dismiss the keyboard when the background of the UITableView is touched. I'm trying to do this by creating a UIButton the size of the UITableView and placing it behind the UITableView. The only problem is the UIButton is catching all the touches even when the touch is on the UITableView. What am I doing wrong?

Thanks!

29 Answers

The UITapGestureRecognizer solution works with table cell selection if you set:

gestureRecognizer.cancelsTouchesInView = NO;

There is Swift 3 version without blocking taps on cells.

In viewDidLoad() method:

let dismissKeyboardGesture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
dismissKeyboardGesture.cancelsTouchesInView = false
tableView.addGestureRecognizer(dismissKeyboardGesture)

And hideKeyboard looks like this:

func hideKeyboard() {
    view.endEditing(true)
}

I did it like this:

Create a method in your TableViewController to deactivate first responder (which would be your TextBox at that point)

- (BOOL)findAndResignFirstResonder:(UIView *)stView {
    if (stView.isFirstResponder) {
        [stView resignFirstResponder];
        return YES;     
    }

    for (UIView *subView in stView.subviews) {
        if ([self findAndResignFirstResonder:subView]) {
            return YES;
        }
    }
    return NO;
}

In tableView:didSelectRowAtIndexPath: call the previous method:

- (void)tableView:(UITableView *)tableView
                             didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    [self findAndResignFirstResonder: self.view];
    ...
}

Try this:

viewDidLoad(){

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))

    tableView.addGestureRecognizer(tap)

}
//Calls this function when the tap is recognized.
@objc func dismissKeyboard() {

    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)

}

UITableView has a handy backgroundView property, with which I achieved this behavior without messing with cell selection, as shown below in Swift:

let tableBackTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
tableView.backgroundView = UIView()
tableView.backgroundView?.addGestureRecognizer(tableBackTapRecognizer)

Swift 4/4.2/5

You can also dismiss the keyboard when a cell is tapped - prior to doing anything else.

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    view.endEditing(true)
    // Do something here
    }

tableView.keyboardDismissMode = .onDrag // .interactive

Why do you want to create a table full of textfields? You should be using a detailed view for each row that contains the text fields. When you push your detailedview, ensure that you call "[myTextField becomeFirstResponder]" so that the user can start editing with just one click away from the table list.

Related