How to detect tap on clear part of UITableView? How to detect tap on clear part of UITableView? ios ios

How to detect tap on clear part of UITableView?


All of the supplied answers, including the accepted answer, add a UITapGestureRecognizer to the tableView; while this will work, I've found that this gesture recognizer can interfere with row taps and triggering didSelectRowAtIndexPath in a somewhat unpredictable/nondeterministic way.

If you want to detect taps in the "blank space" as well as in rows, I highly suggest adding a background view to your table, and add the gesture recognizer there:

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


Yes, there are delegate methods, such as:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

However, this will only tell you if a tap occurs on an existing row. If you want to capture taps on the empty space below the rows (or on a section header) you will need to use a gesture recognizer. You can do something like this:

// in viewDidLoad or somewhere similarUITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tableTapped:)];[self.tableView addGestureRecognizer:tap];//.........- (void)tableTapped:(UITapGestureRecognizer *)tap{    CGPoint location = [tap locationInView:self.tableView];    NSIndexPath *path = [self.tableView indexPathForRowAtPoint:location];    if(path)    {        // tap was on existing row, so pass it to the delegate method        [self tableView:self.tableView didSelectRowAtIndexPath:path];    }    else    {        // handle tap on empty space below existing rows however you want    }}

EDIT: for an alternative approach, consider Connor Neville's approach from his answer on this post and add the gesture recognizer to the table's background.


Thanks to @Stonz2, swift version:

Swift 4

let tap = UITapGestureRecognizer(target: self, action: #selector(tableTapped))self.tableView.addGestureRecognizer(tap)@objc func tableTapped(tap:UITapGestureRecognizer) {    let location = tap.location(in: self.tableView)    let path = self.tableView.indexPathForRow(at: location)    if let indexPathForRow = path {        self.tableView(self.tableView, didSelectRowAt: indexPathForRow)    } else {        // handle tap on empty space below existing rows however you want    }}

Swift 3

let tap = UITapGestureRecognizer(target: self, action: #selector(tableTapped))self.tableView.addGestureRecognizer(tap)func tableTapped(tap:UITapGestureRecognizer) {    let location = tap.location(in: self.tableView)    let path = self.tableView.indexPathForRow(at: location)    if let indexPathForRow = path {        self.tableView(self.tableView, didSelectRowAt: indexPathForRow)    } else {        // handle tap on empty space below existing rows however you want    }}

Swift 2:

let tap = UITapGestureRecognizer(target: self, action: #selector(tableTapped))self.tableView.addGestureRecognizer(tap)func tableTapped(tap:UITapGestureRecognizer) {    let location = tap.locationInView(self.tableView)    let path = self.tableView.indexPathForRowAtPoint(location)    if let indexPathForRow = path {        self.tableView(self.tableView, didSelectRowAtIndexPath: indexPathForRow)    } else {        // handle tap on empty space below existing rows however you want    }}