indexPathForSelectedRow возвращает ноль - PullRequest
18 голосов
/ 31 января 2012

У меня есть UITableViewController с переходом, где я пытаюсь получить выбранную строку:

-(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 возвращается «если путь индекса неверен». Если я добавлю:

        [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:0];
        selectedIndexPath = [self.tableView indexPathForSelectedRow];

selectedIndexPath действителен. Итак, я предполагаю, что строка как-то не выбрана. Может кто-нибудь сказать мне, как выяснить, если это так и что может быть причиной?

Этот код работал нормально, пока я не перешел на использование NSFetchedResultsController (который в противном случае работает). Я также использую indexPathForSelectedRow в нескольких других контроллерах табличного представления, где он работает нормально (один из которых также использует NSFetchedResultsController).

Я также пытался взломать didSelectRowAtIndexPath, но там происходит то же самое. (ожидается, так как он вызывается после prepareForSegue.)

Ответы [ 7 ]

25 голосов
/ 31 января 2012

Возможная причина в том, что вы написали что-то одним из UITableViewDelegate методов -

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

Это обычная практика для deselect the row, который только что был выбран.

Обновление:

В Swift 4.2, xcode 10:

Просто прокомментируйте строку

tableView.deselectRow(at: indexPath, animated: true)

в функции

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
18 голосов
/ 25 ноября 2015

Что-то, что может помочь другим - если вы позвоните reloadData() в вашем табличном представлении, это обнулит indexPathForSelectedRow.

10 голосов
/ 07 апреля 2014

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

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; //add this line after setting indexPath
}
2 голосов
/ 19 февраля 2015

Ok В моем случае я звонил из 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 на CELL" работает и для других.

1 голос
/ 31 января 2012

Хорошо, суть в том, что сцена в раскадровке была испорчена.

Чтобы выяснить это, я удалил последовательность и создал новый пустой класс UITableViewController и добавил только достаточно кода, чтобы я мог нажать нагрести и смотреть на indexPathForSelectedRow.Это было все еще ноль.

Затем я создал новый UITableViewController в раскадровке и заменил существующий.Теперь indexPathForSelectedRow работает.

Я скопировал весь код класса и ячейки прототипа, и он все еще работал!

Из любопытства я посмотрел на источник раскадровки для двух сцен и заметилчто сцена, которая не работала, была намного длиннее новой.Глядя на схему раскадровки, было понятно почему, и удивительно, что это сработало вообще.И теперь я помню, как мне было трудно вырезать и вставлять прототип клеткиДумаю, мне стоит чаще смотреть на режим контура.Смотрите снимок экрана ниже (визуальные сцены выглядят одинаково):

Storyboard screen shot

0 голосов
/ 27 ноября 2018

Swift 4,2

Вы должны указать tableView, какая ячейка выбрана.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") else { return UITableViewCell() }

    let data = products[indexPath.section][indexPath.row]
    cell.update(data: data)

    // Don't use cell.isSelected = true
    if data == selectedData {
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
    }
    return cell
}
0 голосов
/ 13 января 2015

У меня также была эта проблема, когда я заменил класс UITableViewController на класс UIViewController в коде и не обновил раскадровку, т. Е. Я не заменил заполнитель UITableViewController в раскадровке на раскадровку UIViewController.

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