ios 为什么 UITableViewCell 仍然高亮显示?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1840614/
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 16:40:39  来源:igfitidea点击:

Why does UITableViewCell remain highlighted?

iosuitableviewcocoa-touch

提问by 4thSpace

What would cause a table view cell to remain highlighted after being touched? I click the cell and can see it stays highlighted as a detail view is pushed. Once the detail view is popped, the cell is still highlighted.

什么会导致表格视图单元格在被触​​摸后保持突出显示?我单击该单元格,可以看到它在推送详细信息视图时保持突出显示。弹出详细视图后,该单元格仍会突出显示。

回答by paulthenerd

In your didSelectRowAtIndexPathyou need to call deselectRowAtIndexPathto deselect the cell.

在您didSelectRowAtIndexPath需要调用deselectRowAtIndexPath以取消选择单元格。

So whatever else you are doing in didSelectRowAtIndexPathyou just have it call deselectRowAtIndexPathas well.

所以无论你在做什么,didSelectRowAtIndexPath你也可以调用它deselectRowAtIndexPath

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 // Do some stuff when the row is selected
 [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

回答by Danail

The most clean way to do it is on viewWillAppear:

最干净的方法是在 viewWillAppear 上:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // Unselect the selected row if any
    NSIndexPath*    selection = [self.tableView indexPathForSelectedRow];
    if (selection) {
        [self.tableView deselectRowAtIndexPath:selection animated:YES];
    }
}

This way you have the animation of fading out the selection when you return to the controller, as it should be.

这样,当您返回控制器时,您将拥有淡出选择的动画,正如它应该的那样。

Taken from http://forums.macrumors.com/showthread.php?t=577677

取自http://forums.macrumors.com/showthread.php?t=577677

Swift version

迅捷版

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // deselect the selected row if any
    let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
    if let selectedRowNotNill = selectedRow {
        tableView.deselectRow(at: selectedRowNotNill, animated: true)
    }
}

回答by HansPinckaers

Did you subclass -(void)viewWillAppear:(BOOL)animated? The selected UITableViewCell won't deselect when you don't call [super viewWillAppear:animated];in your custom method.

你子类了-(void)viewWillAppear:(BOOL)animated吗?当您不调用[super viewWillAppear:animated];自定义方法时,所选的 UITableViewCell 不会取消选择。

回答by Rutger Huijsmans

For the Swift users, add this to your code:

对于 Swift 用户,请将其添加到您的代码中:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
}

It's paulthenerd's answer except in Swift instead of Obj-C.

这是 paulthenerd 的答案,除了 Swift 而不是 Obj-C。

回答by Oscar

Swift 3 Solution

Swift 3 解决方案

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}

回答by Shantanu

If you are using a UITableViewCell, then comment the following line

如果您使用的是 UITableViewCell,请注释以下行

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{

 // [super setSelected:selected animated:animated];

}

Hope this helps.

希望这可以帮助。

回答by Alessandro Francucci

Updated with Swift 4

使用 Swift 4 更新

After few experiments, also based of previous answers, I've got the conclusion that the best behaviour can be achieved in 2 ways: (almost identical in practice)

经过几次实验,也基于以前的答案,我得出的结论是,可以通过两种方式实现最佳行为:(在实践中几乎相同)

// First Solution: delegate of the table View
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: false)
}

// Second Solution: With the life cycle of the view.
override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    let selectedRow: IndexPath? = tableView.indexPathForSelectedRow
    if let selectedRow = selectedRow {
        tableView.deselectRow(at: selectedRow, animated: false)
    }
}

I'm personally adopting the first solution, because it's simply more concise. Another possibility, if you need a little animation when you return to your tableView, is to use viewWillAppear:

我个人采用第一个解决方案,因为它更简洁。另一种可能性,如果您在返回 tableView 时需要一点动画,则使用viewWillAppear

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let selectedRow: IndexPath? = _view.tableView.indexPathForSelectedRow
    if let selectedRow = selectedRow {
        _view.tableView.deselectRow(at: selectedRow, animated: true)
    }
}

Last but not least, if you're using a UITableViewController, you can also take advantage of the property clearsSelectionOnViewWillAppear.

最后但并非最不重要的一点是,如果您使用 UITableViewController,您还可以利用clearsSelectionOnViewWillAppear属性。

回答by Dave Teare

To get the behaviour Kendall Helmstetter Gelner describes in his comment, you likely don't want deselectRowAtIndexPath but rather the clearsSelectionOnViewWillAppear property on your controller. Perhaps this was set to YES by accident?

要获得 Kendall Helmstetter Gelner 在他的评论中描述的行为,您可能不想要 deselectRowAtIndexPath 而是控制器上的 clearsSelectionOnViewWillAppear 属性。也许这是偶然设置为 YES 的?

See the comment in the default Apple template for new UITableViewController subclasses:

请参阅新 UITableViewController 子类的默认 Apple 模板中的注释:

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;
}

回答by stackoverflowuser2010

I was getting this problem as well for my drill-down application. After a viewcontroller, which I'll call VC, returns after pushing another ViewController, the selected cell in VC remained highlighted. In my app, I had created VC to handle the second level (out of three levels) of my drill-down.

我的向下钻取应用程序也遇到了这个问题。在我将称为 VC 的视图控制器在推送另一个 ViewController 后返回后,VC 中选定的单元格保持突出显示。在我的应用程序中,我创建了 VC 来处理我的向下钻取的第二级(三个级别中)。

The problem in my case is that VC was a UIViewController (that contained a View that contained a TableView). I instead made VC a UITableViewController (that contained a TableView). The UITableViewController class automatically handles the de-highlighting of the table cell after returning from a push. The second answer to the post "Issue with deselectRowAtIndexPath in tableView" gives a more complete answer to this problem.

我的问题是 VC 是一个 UIViewController(它包含一个包含 TableView 的视图)。我改为让 VC 成为 UITableViewController(包含一个 TableView)。UITableViewController 类在从推送返回后自动处理表格单元格的取消突出显示。帖子“在 tableView 中使用 deselectRowAtIndexPath 问题”的第二个答案给出了这个问题的更完整的答案。

The problem did not occur for the root viewcontroller because when I created the app as a "Navigation-based App" in XCode, the resulting root viewcontroller was already made to subclass UITableViewController.

根视图控制器没有出现此问题,因为当我在 XCode 中将应用程序创建为“基于导航的应用程序”时,生成的根视图控制器已经成为 UITableViewController 的子类。

回答by Dave G

If none of these work for you, consider this work-around:

如果这些都不适合您,请考虑以下解决方法:

Use an unwind segue to call:

使用 unwind segue 调用:

@IBAction func unwind_ToTableVC (segue: UIStoryboardSegue) {
    if let index = tableView.indexPathForSelectedRow {
        tableView.deselectRowAtIndexPath(index, animated: true)
    }
}

Why do this? Primarily if you're having trouble getting the deselect code to run at the right time. I had trouble with it not working on the viewWillAppear so the unwind worked a lot better.

为什么要这样做?主要是如果您无法在正确的时间运行取消选择代码。我遇到了无法在 viewWillAppear 上工作的问题,因此放松效果要好得多。

Steps:

脚步:

  1. Write the unwind segue (or paste from above) into your 1st VC (the one with the table)
  2. Go to the 2nd VC. Control-drag from the Cancel/Done/Etc button you're using to dismiss that VC and drag to the Exit Icon at the top.
  3. Select the unwind segue you created in step 1

    Good luck.

  1. 将 unwind segue(或从上面粘贴)写入您的第一个 VC(有桌子的那个)
  2. 转到第二个VC。从用于关闭该 VC 的取消/完成/等按钮按住 Control 键拖动,然后拖动到顶部的退出图标。
  3. 选择您在步骤 1 中创建的 unwind segue

    祝你好运。