IOS: нажатие на UITableView не вызывает didSelectRowAtIndexPath

Мое приложение использует UITableView с UINavigationController, чтобы показать более подробное представление при прослушивании строки таблицы - основной процедуры сверления.

Когда я нажимаю на строку, она подсвечивается, но методы делегата tableView:willSelectRowAtIndexPath: или tableView:didSelectRowAtIndexPath: не вызываются (проверяется с помощью отладчика).

Теперь вот странная часть:

  • В приложении есть несколько других видов таблиц (они не разворачиваются), и ни одна из них не обнаруживает проблемы.

  • Если я нажимаю строку быстро и многократно, после многих попыток (10-20 нормально), tableView:willSelectRowAtIndexPath: и tableView:didSelectRowAtIndexPath: вызываются и обработка продолжается нормально.

  • Проблема возникает только на (на самом деле) iPad под управлением iOS 6. Он отлично работает с iPads, работающим под управлением iOS 5, или с любым iPhone, работающим на любой версии iOS, 6. Он также работает с симулятором iPad, используя iOS 5 или 6.

Итак, кажется, что что-то получает ответ, прежде чем вызываются методы делегата. Но что?

Я не использую UITapGestureRecognizer, поэтому это не проблема. Я не использую несколько таблиц UITableViewControllers для таблицы, поэтому это тоже не проблема.

Ответы

Ответ 1

Резолюция действительно странная: UITableViewController зарегистрирован для всех уведомлений. В обработчике уведомлений данные табличного представления перезагружались с помощью

[self.tableView reloadData]

Согласно Apple DTS, когда таблица перезагружает данные, это вызывает отправку уведомления наблюдателю, вызывая состояние гонки...

Нет объяснений, почему это иногда срабатывало или почему оно всегда срабатывало на iPhone. Но регистрация только для небольшого подмножества уведомлений (т.е. Те, что меня действительно интересовали) устранила проблему!

Ответ 2

У меня была проблема с приложением в iOS6. Метод tableView:didSelectRowAtIndexPath: никогда не запускался, хотя он работал перед обновлением до iOS6.

Я, наконец, понял это, посмотрев на xib и инспектор атрибутов для таблицы. В разделе "Просмотр таблицы" у меня была выбрана опция Выбор, установленная на Нет выбора и Показывать выбор при нажатии.

Изменение параметра Выбор на Единый выбор действительно заставило это работать для меня снова, а оставить Показывать выделение при прикосновении не выбрано, означает, что я не Если выбрана строка, не увидите вспышку или изменение цвета.

Ответ 3

Я столкнулся с подобной проблемой. iOS 6 кажется, намного более чувствительна к малейшему движению вверх по нажатию на ячейку представления таблицы. Похоже, что он регистрирует малейшее движение как запрос прокрутки, а не выбор ячейки. Моему табличному представлению было scrollEnabled = NO потому что это табличное представление со статическими значениями выбора. Табличное представление появляется в небольшой области большего представления iPad. Если я аккуратно коснусь ячейки и подниму ее вверх, ячейка будет выделена.

Чтобы решить эту проблему, я изменил scrollEnabled на YES и убедился, что область, выделенная для моего tableView, была больше, чем фактическая область, необходимая для отображения табличного представления, таким образом предотвращая прокрутку. Не уверен, что это является причиной проблемы, с которой вы столкнулись, но надеюсь, что это поможет.

Ответ 4

У меня была та же проблема. UITableView не запускал метод didSelectRowAtIndexPath при работе в iOS6, но он отлично работал в iOS5.1.

Я также реализовал

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath{
    return NO;
}

и возвратил NO. В iOS5 все работало нормально, но в тот же момент, когда я переключился на iOS6, он перестанет запускать didSelectRowAtIndexPath. Как только я удалил этот метод shouldHighlightRow, все снова работало в iOS6. Ура!

Ответ 5

Обычная причина того, что didSeletRowAtIndexPath() не вызывается, заключается в наличии UITapGestureRecognizer на вашем контроллере представления с Cancels touches Отмены в представлении, установленном в YES.

Правильное и единственное разумное решение состоит в том, чтобы установить Cancels touches в виду NO. Тогда ваш выбор строки таблицы должен работать хорошо.

Очевидно, что это имеет некоторые последствия в ваших обработчиках жестов - вам может понадобиться добавить некоторый код в ваш обработчик жестов, чтобы остановить некоторые касания, происходящие с вашими представлениями, т.е.

- (IBAction)onTapGesture:(UITapGestureRecognizer *)sender {

    if (sender.view == someOldViewThatINeedToDealWith) {
        sender.cancelsTouchesInView = true;
    }
}

Ответ 6

Я пробовал все остальные ответы, и хотя они казались многообещающими, они не решили проблему.

С тех пор я обнаружил причину проблемы в моем случае: я вызывал [self.tableView reloadData] в другом потоке (из-за обработки события NSNotification, отправленного из рабочего рабочего потока).

Я исправил проблему, изменив [self.tableView reloadData] на

[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

Надеюсь, что это поможет.

Ответ 7

Другой подозреваемый может быть признаком распознавания жеста, установленным в представлении контроллера вида, поглощающим все краны, такие как черная дыра. Удалите распознаватель жестов, чтобы включить выбор. У меня была одна и та же проблема, и причина нажатия была причиной.

Ответ 8

Настройка

recognizer.cancelsTouchesInView = NO;

заботится об этом, если ваш вариант использования позволяет одновременно обрабатывать касаний с помощью [tap] распознавателя жестов (например, kdb) и вид, к которому прикреплен распознаватель.

Ответ 9

в моем случае я получил кнопку, которая получила все события касания до tableviewcell