Почему -didDeselectRowAtIndexPath не вызывается?

Я создал новый проект (приложение Xcode 4, приложение Master-Detail), чтобы увидеть, что я делаю что-то неправильно, но у меня все еще такая же проблема. Я хочу вызвать -reloadData, когда пользователь отменяет выбор ячейки, поэтому это мой код:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
    [tableView reloadData];
}

-(NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"%s", __PRETTY_FUNCTION__);
    return indexPath;
}

Проблема заключается в том, что didDeselectRowAtIndexPath и willDeselectRowAtIndexPath, кажется, не вызываются. Это ожидаемое поведение? Документы для tableView:didDeselectRowAtIndexPath: state

Сообщает делегату, что указанная строка теперь не выбрана.

поэтому я думаю, что он должен работать, как я думал.

Ответ 1

в документации tableView:willDeselectRowAtIndexPath: также говорится, что

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

Это не сработало для нас, когда я использовал UITableViewCellSelectionStyleNone.

Ответ 2

Если вы вызываете deselectRowAtIndexPath:animated:, сообщения делегата tableView:willDeselectRowAtIndexPath: и tableView:didDeselectRowAtIndexPath: не отправляются.

Ответ 3

Еще одна причуда, которую я нашел - в IOS 5.1, во всяком случае, заключается в том, что если вы вызываете reloadData в таблице, вы не получите didDeselectRowAtIndexPath для любых выбранных строк. В моем случае я немного корректирую компоновку ячеек в зависимости от того, выбрана она или нет, поэтому мне нужно вручную выполнить эту работу до перезагрузки данных таблицы.

Ответ 4

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

Если вы используете

[tableView reloadData]

Затем данные таблицы перезагружаются и никакие строки не выбираются за кулисами - это означает

только

didSelectRowAtIndexPath

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

Ответ 5

Чистый способ решения этой проблемы - сделать следующее:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)
    // Do your cell setup work here...

    //If your cell should be selected...
    if cellShouldBeSelected {
        tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None)
    }

    return cell
}

Это решает всю проблему ячейки, которая не отвечает на отмену после вызова tableView.reloadData().

Ответ 6

Установите allowsMultipleSelection для этого табличного представления на TRUE

  self.tableView.allowsMultipleSelection = YES;

Ответ 7

Я думаю, что это просто ошибка! Почему бы вам не использовать следующее:

[self.tableView deselectRowAtIndexPath:indexPath animated:YES];

Вместо того, чтобы использовать только "tableView" в этой строке?
Полагаю, и уверен, что вышеприведенная линия даст вам решение!
надеюсь, что это помогло вам, если бы вы оглянулись на свой старый вопрос!!!
Престижность!:)

Ответ 8

Когда какая-либо ячейка выбрана в первый раз, метод -[UITableViewDelegate tableView:didDeselectRowAtIndexPath:] не вызывается, а -[UITableViewDelegate tableView:didSelectRowAtIndexPath:]. После выбора еще одной ячейки, didDeselectRowAtIndexPath вызывается сразу после didSelectRowAtIndexPath.

Это нормально.

Но если вам нужно показать ячейку, выбранную в начале, (eq с помощью UITableViewCellAccessoryCheckmark), то после выбора другой ячейки вы, вероятно, хотите, чтобы метод didDeselectRowAtIndexPath вызывался в первый раз, чтобы отменить выбор предыдущей ячейки.

Решение!

Вы должны вызвать -[UITableView selectRowAtIndexPath:animated:scrollPosition:] в -[UITableViewDataSource tableView:cellForRowAtIndexPath:], чтобы уведомить, что выбранная ячейка уже выбрана.

Objective-C

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    // saving the current selected row
    SelectedRow = indexPath.row;
}

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryNone;
}

#pragma mark - UITableViewDataSource

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }

    // preventing selection style
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    cell.textLabel.text = "Some text";

    if (indexPath.row == SelectedRow) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        // just wanted to make it selected, but it also can scroll to the selected position
        [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
    }

    return cell;
}

Swift 3.1

// MARK: - UITableViewDelegate

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)!
    cell.accessoryType = UITableViewCellAccessoryType.checkmark
    selectedRow = indexPath.row
}

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)!
    cell.accessoryType = UITableViewCellAccessoryType.none
}

// MARK: - UITableViewDataSource

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")

    // preventing selection style
    cell.selectionStyle = UITableViewCellSelectionStyle.none

    cell.textLabel?.text = "some text"

    if (indexPath.row == selectedRow) {
        cell.accessoryType = UITableViewCellAccessoryType.checkmark
        // just wanted to make it selected, but it also can scroll to the selected position
        tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
    }

    return cell
}