UITableView Row Persistance - почему происходит сбой didSelectRowAtIndexPath

У меня есть UITableView, в котором выбранная строка хранится в пользовательских настройках по умолчанию. tableView является частью структуры меню, которая может быть перезагружена в течение всего срока службы приложения, поэтому я хочу сохранения между загрузками. В viewDidLoad этот UserDefault проверяется на существование, и я вызываю

NSIndexPath *path = [NSIndexPath indexPathForRow:row inSection:0];
    [self.tableView selectRowAtIndexPath:path animated:NO scrollPosition:(UITableViewScrollPositionMiddle)];

Это работает нормально, как и ожидалось. Однако на самом деле он не выбирает строку, а просто выделяет ее. Если я впоследствии позвоню

[self tableView:self.tableView didSelectRowAtIndexPath:path];

Я получаю сбой - «неопознанный селектор отправлен в экземпляр». Почему?


person Skybird    schedule 02.02.2012    source источник
comment
Состояние строки должно быть установлено в вашей модели. Поэтому, если элемент меню выбран, модель данных вашего меню должна иметь выбранный элемент. Чтобы показать его как выбранный, вам просто нужно перезагрузить таблицу. Если вы хотите выбрать его программно, вы просто устанавливаете значение модели как выбранное, выполняете тот же метод, который вы бы использовали, если бы пользователь выбрал его вручную, и перезагружаете таблицу, чтобы элемент меню отображался выбранным для пользователя.   -  person David Rutgos    schedule 06.07.2012


Ответы (2)


[self tableView:self.tableView didDeselectRowAtIndexPath:path] вызовет ВАШУ реализацию метода отмены выбора (который определен в UITableViewDelegate).

Вы получаете сбой, поскольку не реализовали его в своем делегате.

Вам следует позвонить: [self.tableView deselectRowAtIndexPath:path animated:NO];

person Gilad Novik    schedule 02.02.2012
comment
Привет Гилад, спасибо за ответ. Я сделал ошибку в исходном посте, а именно поставил didDeselect, вместо didSelect. Моя ошибка, извините. Однако изменение метода по-прежнему оставляет мою проблему. Если я попробую ваш метод, соответствующим образом изменив имя: [self.tableView SelectRowAtIndexPath: анимированный путь: NO]; - У меня это работает в соответствии с исходным сообщением. То есть я могу выбрать строку, но не запускать действие, запускающееся при выборе строки в didSelectRowAtIndexPath. Если я попробую [self.tableview didSelectRowAtIndexPath...], я получу ошибку компилятора - UITableView не объявляет селектор с именем... - person Skybird; 03.02.2012
comment
didSelectRowAtIndexPath - это метод протокола, реализованный вашим классом, а не UITableView, поэтому он жалуется. - person David Rutgos; 03.02.2012
comment
В качестве краткого руководства - все методы, начинающиеся с did или will (didDeselect, willSelect и т. д.), являются методами обратных вызовов, реализованными ВАМИ. Они вызываются соответствующим элементом управления (UITableView в вашем случае) и никогда не должны вызываться непосредственно программистом. Обычно элемент управления реализует вызов (например, deselectRowAtIndexPath), который вы можете использовать. Очень часто обратные вызовы вызываются только на основе взаимодействия с пользователем через графический интерфейс. Если вы выбираете/отменяете выбор ячейки программно - вы также должны вызывать свой собственный обратный вызов (если он реализован). - person Gilad Novik; 06.02.2012

UITableView работает через два протокола делегирования: UITableViewDelegate и UITableViewDataSource. Класс, который определяет ваш UITableView, должен реализовывать эти протоколы, и вы должны установить делегат и источник данных UITableView на «я». Вы не должны напрямую вызывать методы протокола, что, скорее всего, является причиной вашего сбоя.

Чтобы выбрать конкретную строку на основе вашей модели данных (пользовательская по умолчанию), вам необходимо установить UITableViewCell выбрал значение "YES" в tableView:cellForRowAtIndexPath: для отображаемой строки.

Я рекомендую пройти этот учебник, чтобы помочь вам лучше понять UITableView.

http://www.iosdevnotes.com/2011/10/uitableview-tutorial/

person David Rutgos    schedule 03.02.2012