Как обнаружить краны на прозрачной части UITableView?

У меня есть контроллер просмотра с UITableView. Высота табличного представления статична и == высота экрана. Количество строк в таблице может меняться, и иногда это может быть ситуация, когда количество строк меньше числа строк, которые могут быть видимыми, поэтому появляется некоторая ясная область внизу таблицы. Могу ли я обнаружить кран на нем без распознавателя жестов? Существуют ли некоторые методы делегата UITableView?

Ответы

Ответ 1

Да, существуют методы делегата, такие как:

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

Однако это только скажет вам, происходит ли крана в существующей строке. Если вы хотите захватить краны в пустом пространстве под строками (или в заголовке раздела), вам нужно будет использовать распознаватель жестов. Вы можете сделать что-то вроде этого:

// in viewDidLoad or somewhere similar
UITapGestureRecognizer *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: для альтернативного подхода рассмотрите подход Коннора Невилла от его ответа на этот пост и добавьте распознаватель жестов в фон стола.

Ответ 2

Благодаря @Stonz2, быстрая версия:

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
    }
}

Ответ 3

Все предоставленные ответы, включая принятый ответ, добавьте UITapGestureRecognizer в tableView; в то время как это сработает, я обнаружил, что этот распознаватель жестов может вмешиваться в краны строк и запускать didSelectRowAtIndexPath несколько непредсказуемым/недетерминированным способом.

Если вы хотите обнаружить краны в "пробеле", а также в строках, я настоятельно рекомендую добавить фоновое представление к вашей таблице и добавить там распознаватель жестов:

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

Ответ 4

Вам не нужен распознаватель жестов. Вы должны ввести <UITableViewDelegate> в свой ViewController.h, а затем добавить этот метод в свой ViewController.m:

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

где indexPath - индекс щелкнутой строки/столбца.