题 如何禁用UITableView选择突出显示?


当你点击一行时 UITableView,该行被突出显示并被选中。是否可以禁用此功能,因此点击一行什么都不做?


1076
2017-10-10 11:32


起源


原来的问题标题不好。 OP希望主要是禁用 selection, 而且当然 highlighting 被禁用了。许多高投票的答案解释了如何 disable selection并没有解决禁用问题 highlighting。禁用仅突出显示使用 cell.selectionStyle = .None 或者去 storyboard / cell / Selection = None - Andrej
请更新标题或帖子。我很困惑。基于这个问题,我不知道提供答案的目的是什么。 - Dani Springer


答案:


对我来说,以下工作正常:

tableView.allowsSelection = NO;

意即 didSelectRowAt# 根本行不通。也就是说,触摸桌子的一排,就这样,绝对不会做任何事情。 (因此,显然,永远不会有选定的动画。)

(注意,如果在细胞上,你有 UIButton 或任何其他控件,当然这些控件仍然有效。您碰巧在表格单元格上拥有的任何控件与UITableView允许您“选择行”的能力完全无关 didSelectRowAt#。)


498
2017-07-22 16:56



这最终对我有用,我试着用cell.selectionStyle = UITableViewCellSelectionStyleNone;但它不起作用。有一点需要注意:它应该是:tableView.allowsSelection = NO;不是假的。 - tony.tc.leung
我想,这是最好的选择。单元格上的按钮处于活动状态,但文本不活动。 - Fahim Parkar
这也完全禁用你的细胞...... - Gil Sand
这是如何被接受的答案,并有这么多的票?它完全没有回答这个问题!你需要设置 selectionStyle 细胞上的财产: cell.selectionStyle = UITableViewCellSelectionStyle.None 在斯威夫特,或 cell.selectionStyle = UITableViewCellSelectionStyleNone 在Objective-C中。 - nodebase
根据需要,有几种方法可以做到这一点。没有选择风格和选择都不会起作用,或者都可能失败。这是一个例子。如果你想选择单元格并拥有 tableViewDidSelectRowAtIndexPath 被称为, cell.selectionStyle = .None 是理想的。如果您不想要或不关心要调用该委托函数(即在tableViewCell中有文本字段)设置 tableView.allowsSelection = false 很好。 - Made2k


您所要做的就是在上面设置选择样式 UITableViewCell 实例使用:

Objective-C的:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

要么

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

斯威夫特2:

cell.selectionStyle = UITableViewCellSelectionStyle.None

Swift 3和4.x:

cell.selectionStyle = .none

此外,请确保您要么不实施 -tableView:didSelectRowAtIndexPath: 在您的表视图中委托或明确排除您希望不执行任何操作的单元格。

更多信息在这里 和 这里


1830
2017-10-10 13:22



ARRRRRRRGH更好的方法是使用cell.userInteractionEnabled = NO;这不仅会停止高亮度的单元格,而且还会停止触发didSelectRowAtIndexPath的特定单元格......... - Tony Million
@Tony如果你在单元格内有一个UITextField,这是个坏主意。 - Aniruddh Joshi
@TonyMillion如果你想使用内置的编辑控件,比如刷卡到删除,这也是一个坏主意。如果将userInteractionEnabled设置为NO,则删除按钮不会响应用户触摸事件。 - Carlos P
迟到此线程,但使用cell.allowsSelection而不是userInteraction。这会阻止单元格的交互方法,但不会阻止常规的UIView响应程序。 - Chris C
我将对答案进行投票,但为了清楚起见,OP仅要求禁用“突出显示”,否则禁用整个单元格交互,因此所有这些评论都是非正式的。 - Frederic Yesid Peña Sánchez


因为我最近阅读了这篇文章,它帮助了我,我想发布另一个答案来巩固所有的答案(后代)。



因此,根据您所需的逻辑和/或结果,实际上有5种不同的答案:

1.要禁用蓝色突出显示而不更改单元格的任何其他交互:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

当我在UITutViewCell中托管UIButton或其他控件时,我使用它,我希望用户能够与控件交互,但不能与单元本身交互。

注意:正如Tony Million上面提到的,这并不能阻止 tableView:didSelectRowAtIndexPath:。我通过简单的“if”语句来解决这个问题,通常会测试该部分并避免针对特定部分采取措施。

我想要测试这样一个单元格的另一种方法是:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // A case was selected, so push into the CaseDetailViewController
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if (cell.selectionStyle != UITableViewCellSelectionStyleNone) {
        // Handle tap code here
    }
}



2.要对整个表格执行此操作,您可以将上述解决方案应用于表格中的每个单元格,但您也可以这样做:

[tableView setAllowsSelection:NO];

在我的测试中,这仍然允许内部的控件 UITableViewCell 互动。


3.要使单元格为“只读”,您可以简单地执行此操作:

[cell setUserInteractionEnabled:NO];



4.使整个表格“只读”

[tableView setUserInteractionEnabled:NO];



5.即时确定是否突出显示一个单元格(根据 这个答案 隐含地包括选择),您可以实现以下内容 UITableViewDelegate 协议方法:

- (BOOL)tableView:(UITableView *)tableView 
   shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath

333
2018-06-10 11:08



如果从笔尖加载单元格设计,则复选框(在IB中)将适用于#3(以及#4的表格)。对于#4 vs#2,单元格内的控件是否具有交互性是有区别的吗? - lilbyrdie
是。如果要禁用选择但允许UIButtons等...继续支持用户交互,请使用#2。如果您想要一个完全只读的单元格,请使用#4。当然,为什么你会在非交互式单元格中拥有除UIViews或UILabels之外的任何内容。也许有人会想要在发生其他事情时禁用所有交互。 - mbm29414
#4是一个糟糕的主意,这样做也会禁用表格视图中的滚动 - simon
@simon实际上,这不是一个可怕的想法;根据您的具体情况,这是一个可能或可能不是一个好选择的选项。此外,#4禁用用户滚动;如果有必要,你仍然可以实现自己的。我同意#4没用多少,但这并不是一个糟糕的主意。 - mbm29414
为了完整性,你可以加入一个喊叫声 tableView:shouldHighlightRowAtIndexPath:,是的 通常 (并不总是)我的首选方法。 - Benjohn


根据我自己的实施经验总结我认为正确的答案:

如果要禁用某些单元格的选择,请使用:

cell.userInteractionEnabled = NO;

除了阻止选择之外,这还会阻止tableView:didSelectRowAtIndexPath:为设置它的单元格调用。 (感谢Tony Million的回答,谢谢!)

如果您的单元格中有按钮需要单击,则需要改为:

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

你还需要忽略对单元格的任何点击 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

如果要禁用整个表的选择,请使用:

tableView.allowsSelection = NO;

(感谢Paulo De Barros,谢谢!)


75
2018-06-01 13:32



怎么样如果我们的单元格中有一个按钮? - Umair Afzal


从iOS 6.0开始, UITableViewDelegate 具有 tableView:shouldHighlightRowAtIndexPath:。 (在iOS上阅读它 文档。)

此方法允许您将特定行标记为不可突出(并且隐式,不可选),而无需更改单元格的选择样式,弄乱单元格的事件处理 userInteractionEnabled = NO,或此处记录的任何其他技术。


49
2017-10-31 21:48



偶然发现了这个帖子,我很惊讶在这之前看到了很多其他的答案。毫无疑问,这是正确的方法。 - beebcon
这确实是应该考虑的正确和唯一的答案。提及userInteraction的任何其他内容都是完全错误的。 - mattyohe


您还可以通过选择禁用界面构建器本身的行选择 NoSelection 来自 selection 检查器窗格中的选项(UITableView属性),如下图所示

UITableView Inspector


45
2018-04-25 13:13



最佳解决方案IMHO - Itai Spector
我经常使用这个解决方案 - Evsenev


SWIFT的固定解决方案3 

cell.selectionStyle = .none

42
2018-01-07 19:15



这似乎比选择的答案要好得多...... - LIAM BOLLING


如果有人需要回答 迅速

cell.selectionStyle = .None

33
2017-12-02 09:39



我们也可以使用这个cell.selectionStyle = UITableViewCellSelectionStyle.None - bably


如果您希望选择仅闪光,而不是保持在选定状态,您可以打电话

didSelectRowAtIndexPath

下列

[tableView deselectRowAtIndexPath:indexPath animated:YES];

所以它会闪烁所选状态并恢复。


31
2017-11-13 15:07



通过这种方法,行立即突出显示,然后在半秒内消失。这就是Apple设置菜单的样式,所以它对我来说很好看。 - VinceFior


在你的 UITableViewCellXIB 在Attribute Inspector中设置值 Selection 至 None

enter image description here


28
2017-10-05 07:49



为什么要投票,没有解释? - Zaid Pathan
这正是我所需要的。我仍然想要didSelect ...通知但没有明显的选择指示。谢谢! - Timothy Tripp
很高兴它有帮助! :) - Zaid Pathan


来自 UITableViewDelegate 您可以使用该方法的协议 willSelectRowAtIndexPath  和 return nil 如果您不想选择该行。

以同样的方式你可以使用 willDeselectRowAtIndexPath 方法和 return nil 如果您不希望取消选择该行。


27
2018-06-30 10:01



我不喜欢这种方法,因为它仍会显示处于突出显示状态的单元格,直到触摸为止。 - kbanman
这正是我喜欢它的原因:-) - Joris Weimar