ios 为什么没有调用 -didDeselectRowAtIndexPath?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9819672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:28:39  来源:igfitidea点击:

Why is -didDeselectRowAtIndexPath not being called?

iosuitableview

提问by phi

I created a fresh project (Xcode 4, Master-Detail application) just to see if I'm doing something wrong, but I still have the same problem. I want to call -reloadDatawhen the user deselectsa cell, so this is my code:

我创建了一个新项目(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;
}

The problem is that didDeselectRowAtIndexPathand willDeselectRowAtIndexPathdon't seem to be called. Is this the expected behavior? The docs for tableView:didDeselectRowAtIndexPath:state

问题是,didDeselectRowAtIndexPathwillDeselectRowAtIndexPath似乎并没有被调用。这是预期的行为吗?tableView:didDeselectRowAtIndexPath:状态文档

Tells the delegate that the specified row is now deselected.

告诉委托指定的行现在已取消选择。

so I guess that it should work as I thought.

所以我想它应该像我想的那样工作。

采纳答案by beryllium

the documentation of tableView:willDeselectRowAtIndexPath:also says that

的文档tableView:willDeselectRowAtIndexPath:也说

This method is only called if there is an existing selection when the user tries to select a different row. The delegate is sent this method for the previously selected row. You can use UITableViewCellSelectionStyleNoneto disable the appearance of the cell highlight on touch-down.

仅当用户尝试选择不同的行时存在现有选择时才会调用此方法。为先前选定的行发送此方法的委托。您可以使用 UITableViewCellSelectionStyleNone禁用触摸屏时单元格突出显示的外观。

It not worked for we when I used UITableViewCellSelectionStyleNone.

当我使用UITableViewCellSelectionStyleNone.

回答by freytag

If you call deselectRowAtIndexPath:animated:, the delegate methods tableView:willDeselectRowAtIndexPath:and tableView:didDeselectRowAtIndexPath:message are not sent.

如果您调用deselectRowAtIndexPath:animated:,则不会发送委托方法tableView:willDeselectRowAtIndexPath:tableView:didDeselectRowAtIndexPath:消息。

回答by Andrew

One other quirk that I've found — in IOS 5.1, at any rate — is that if you call reloadDataon the table, you won't get didDeselectRowAtIndexPathfor any selected rows. In my case, I adjust the cell layout slightly depending on whether it's selected or not, so I needed to manually do that work prior to reloading the table data.

我发现的另一个怪癖——至少在 IOS 5.1 中——是如果你调用reloadData表,你不会得到didDeselectRowAtIndexPath任何选定的行。就我而言,我根据是否选中它稍微调整单元格布局,因此我需要在重新加载表格数据之前手动执行该工作。

回答by James

I know this is an old question but I just ran into the same problem.

我知道这是一个老问题,但我遇到了同样的问题。

If you use

如果你使用

[tableView reloadData]

Then The table data is reloaded and no rows are selected behind the scenes - meaning

然后重新加载表数据并且在幕后没有选择任何行 - 意思是

only

只要

didSelectRowAtIndexPath

is ever called. I hope this helps someone who comes across this problem.

曾经被称为。我希望这可以帮助遇到这个问题的人。

回答by kevmalek

A clean way of solving this problem is to do the following:

解决此问题的一种简洁方法是执行以下操作:

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
}

This solves this entire problem of a cell not responding to being deselected after a tableView.reloadData()call happens.

这解决了在tableView.reloadData()呼叫发生后单元不响应被取消选择的整个问题。

回答by Zsivics Sanel

When any cell is selected the first time, the -[UITableViewDelegate tableView:didDeselectRowAtIndexPath:]method is not called, but the -[UITableViewDelegate tableView:didSelectRowAtIndexPath:]. Just after selecting one more cell, the didDeselectRowAtIndexPathis called right after the didSelectRowAtIndexPath.

当第一次选择任何单元格时,-[UITableViewDelegate tableView:didDeselectRowAtIndexPath:]不会调用该方法,而是调用-[UITableViewDelegate tableView:didSelectRowAtIndexPath:]. 再选择一个单元格后, 就在 之后didDeselectRowAtIndexPath调用didSelectRowAtIndexPath

This is OK.

还行吧。

But if you have to show a cell as selected at the begining, (e.q. using UITableViewCellAccessoryCheckmark), then, after selecting another cell you probably want the didDeselectRowAtIndexPathmethod being called the first time, to deselect the previous cell.

但是,如果您必须在开始时显示选定的单元格(使用 eq UITableViewCellAccessoryCheckmark),那么在选择另一个单元格后,您可能希望didDeselectRowAtIndexPath第一次调用该方法,以取消选择前一个单元格。

The solution!

解决方案!

You have to call the -[UITableView selectRowAtIndexPath:animated:scrollPosition:]in the -[UITableViewDataSource tableView:cellForRowAtIndexPath:]to notify that a wanted cell is already selected.

您必须调用-[UITableView selectRowAtIndexPath:animated:scrollPosition:]中的-[UITableViewDataSource tableView:cellForRowAtIndexPath:]来通知已经选择了想要的单元格。

Objective-C

目标-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

斯威夫特 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
}

回答by Kannan Prasad

Set allowsMultipleSelectionfor that tableview to TRUE

allowsMultipleSelection将该 tableview设置为TRUE

  self.tableView.allowsMultipleSelection = YES;

回答by Randika Vishman

I think it's just simple mistake! Why don't you use following:

我认为这只是一个简单的错误!为什么不使用以下内容:

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

Instead of using just "tableView" in that line?
I guess, and pretty sure that above line would give you the solution!
hope this helped you, if you looked back at your old question!!!
Kudos! :)

而不是在该行中仅使用“tableView”?
我想,并且很确定上面的行会给你解决方案!
希望这对你有帮助,如果你回顾你的旧问题!!!
荣誉!:)

回答by Abdelrahman Fouda

You just have to set the selection to be "Multiple Selection" as Xcode allow you to deselect the cells in this mode only.

您只需将选择设置为“多选”,因为 Xcode 仅允许您在此模式下取消选择单元格。

Xcode Screenshot

Xcode 截图

回答by Hyman

For me it's started working by adding ->super.setSelected(selected, animated: animated)

对我来说,它通过添加开始工作 ->super.setSelected(selected, animated: animated)

override func setSelected(_ selected: Bool, animated: Bool) {
   super.setSelected(selected, animated: animated)//This was missing
}