IndexPathForSelectedRow возвращает ноль
У меня есть UITableViewController с segue, где я пытаюсь получить текущую выбранную строку:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:@"EditFilterElementSegue"]){
// Get the element that was clicked and pass it to the view controller for display
NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
Element *element = [fetchedResultsController objectAtIndexPath:selectedIndexPath];
FilterElementTableViewController *vc = segue.destinationViewController;
vc.filter = filter;
vc.element = element;
}
}
Проблема заключается в том, что indexPathForSelectedRow возвращает nil. Документы говорят, что nil возвращается "если указательный путь недействителен". Если я добавлю:
[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:0];
selectedIndexPath = [self.tableView indexPathForSelectedRow];
selectedIndexPath действителен. Итак, я в настоящее время предполагаю, что строка как-то становится невыбранной. Может ли кто-нибудь сказать мне, как выяснить, если это так и что может быть причиной?
Этот код работал нормально, пока я не переработал NSFetchedResultsController (который в противном случае работает). Я также использую indexPathForSelectedRow в нескольких других контроллерах табличных представлений, где он отлично работает (один из которых также использует NSFetchedResultsController).
Я также пытался взломать didSelectRowAtIndexPath, но то же самое происходит там. (ожидается, поскольку он вызвал после prepareForSegue.)
Ответы
Ответ 1
Хорошо, нижняя строка сцены в раскадровке была испорчена.
Чтобы понять это, я удалил segue и создал совершенно новый пустой класс UITableViewController и добавил только достаточно кода, чтобы я мог щелкнуть по строке и посмотреть на indexPathForSelectedRow. Это было еще ноль.
Затем я создал новый UITableViewController в раскадровке и заменил существующий. Теперь работал indexPathForSelectedRow.
Я скопировал весь код класса и прототипы ячеек, и он все еще работает!
Из любопытства я посмотрел источник раскадровки на две сцены и заметил, что сцена, которая не работала, была намного длиннее новой. Глядя на схему раскадровки, было очевидно, почему, и удивительно, что это сработало. И теперь я помню, что у меня были проблемы с резанием и вклеиванием прототипа. Думаю, я должен чаще смотреть на схему. См. Снимок экрана ниже (визуальные сцены выглядят одинаково):
![Storyboard screen shot]()
Ответ 2
Возможная причина в том, что вы написали что-то в одном из методов UITableViewDelegate
-
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
Это обычная практика только для deselect the row
.
Ответ 3
Что-то, что может помочь другим пользователям - если вы вызываете reloadData()
в своем представлении таблицы, это означает indexPathForSelectedRow
.
Ответ 4
Убедитесь, что вы не вызываете метод deselectRowAtIndexPath
, прежде чем получить путь указателя к выбранному столбцу.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES]; //add this line after setting indexPath
}
Ответ 5
Хорошо. В моем случае я звонил из UIButton в раскадровке с помощью show segue.
И удаление следующей строки:
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
с ниже 2 строк работал у меня:
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
надеюсь, что мой случай "вызов segue из UIButton on CELL" также работает и для других.
Ответ 6
У меня также была эта проблема, когда я заменил класс UITableViewController классом UIViewController в коде и не обновлял раскадровку, то есть я не заменил заполнитель UITableViewController в раскадровке с раскадрой UIViewController.