如何禁用 UITableView 选择?

How can I disable the UITableView selection?

提问人:davidmytton 提问时间:10/10/2008 最后编辑:Malikdavidmytton 更新时间:11/3/2022 访问量:537247

问:

当您点击 中的一行时,该行将突出显示并处于选中状态。是否可以禁用此功能,以便点击一行不执行任何操作?UITableView

iOS UITableView 可可触摸

评论

25赞 Andrej 9/7/2017
原来的问题有一个糟糕的标题。OP 想要的主要是禁用,当然也会因此被禁用。许多高票答案解释了如何和不解决禁用问题。要禁用仅突出显示,请使用或转到selectionhighlightingdisable selectionhighlightingcell.selectionStyle = .Nonestoryboard / cell / Selection = None
0赞 6/21/2018
请更新标题或帖子。 我很困惑。基于这个问题,我不知道提供的答案是做什么的。

答:

2026赞 Martin Gordon 10/10/2008 #1

您所要做的就是使用以下任一方法在实例上设置选择样式:UITableViewCell

目标-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

斯威夫特 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None

Swift 3 和 4.x:

cell.selectionStyle = .none

此外,请确保您要么不在表视图委托中实现,要么显式排除您希望不执行任何操作的单元格(如果确实实现了它)。-tableView:didSelectRowAtIndexPath:

更多信息 这里 和 这里

评论

123赞 Aniruddh 9/18/2011
@Tony 如果单元格内有 UITextField,则不是一个好主意。
74赞 Carlos P 10/26/2011
@TonyMillion如果您想使用内置的编辑控件(例如滑动删除),这也是一个坏主意。如果将 userInteractionEnabled 设置为 NO,则删除按钮不会响应用户触摸事件。
49赞 Chris C 7/10/2012
迟到此线程,但使用 cell.allowsSelection 而不是 userInteraction。这会停止单元格的交互方法,但不会阻止常规 UIView 响应程序的内容。
4赞 user4951 10/15/2012
设置 cell.userInteractionEnable=No 不会停止触发 didSelectRowAtIndexPath。
25赞 Frederic Yesid Peña Sánchez 4/2/2014
我会对答案投赞成票,但需要明确的是,OP 只要求禁用“突出显示”,不禁用整个单元格交互,所以所有这些评论都是题外话。
31赞 user41806 6/30/2009 #2

在协议中,您可以使用该方法,如果您不希望选择该行。UITableViewDelegatewillSelectRowAtIndexPathreturn nil

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

评论

6赞 kbanman 2/14/2010
我不喜欢这种方法,因为它仍然显示单元格处于突出显示状态,直到修饰为止。
2赞 Joris Weimar 11/10/2011
这正是我喜欢它的原因:-)
651赞 Paulo De Barros 7/23/2009 #3

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

tableView.allowsSelection = false

这意味着根本行不通。也就是说,触摸桌子的一排,就其本身而言,绝对无济于事。(因此,很明显,永远不会有选定的动画。didSelectRowAt#

(请注意,如果在单元格上,您有或任何其他控件,当然这些控件仍然有效。您碰巧在表单元格上拥有的任何控件都与 UITableView 允许您使用 . “选择行”的功能完全无关。UIButtondidSelectRowAt#

需要注意的另一点是:当处于编辑模式时,这不起作用。要在编辑模式下限制单元格选择,请使用以下代码:UITableView

tableView.allowsSelectionDuringEditing = false 

评论

6赞 tony.tc.leung 5/22/2010
这终于对我有用了,我尝试使用 cell.selectionStyle = UITableViewCellSelectionStyleNone;但它没有用。需要注意的一点是:tableView.allowsSelection = NO;不是假的。
6赞 Fahim Parkar 2/10/2013
我认为,这是最好的选择。单元格上的按钮处于活动状态,但文本不处于活动状态。
544赞 nodebase 9/23/2015
这是如何被接受的答案,并且有这么多的赞成票?它根本没有回答这个问题!您需要在单元格上设置属性:在 Swift 中,或在 Objective-C 中。selectionStylecell.selectionStyle = UITableViewCellSelectionStyle.Nonecell.selectionStyle = UITableViewCellSelectionStyleNone
5赞 Khanad 2/15/2016
这在 swift 2 中对我有用。tableView.allowSelection = false
16赞 Made2k 2/16/2016
有几种方法可以做到这一点,具体取决于所需的内容。没有选择样式和任何选择都可能同时起作用,也可能同时失败。下面是一个示例。如果要选择单元格并调用单元格,则需要。如果您不希望或不关心调用该委托函数(即在 tableViewCell 中有一个文本字段),设置就可以了。tableViewDidSelectRowAtIndexPathcell.selectionStyle = .NonetableView.allowsSelection = false
20赞 Denis Kutlubaev 5/27/2011 #4

尝试输入:

cell.selected = NO;

它会在需要时取消选择您的行。

在 Swift3 中...

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let r = indexPath.row
    print("clicked .. \(r)")
    tableView.cellForRow(at: indexPath)?.setSelected(false, animated: true)
}
91赞 JosephH 6/1/2011 #5

根据我自己在实现这一点方面的经验,总结一下我认为是正确的答案:

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

cell.userInteractionEnabled = NO;

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

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

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

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

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

tableView.allowsSelection = NO;

(感谢 Paulo De Barros,谢谢!

评论

0赞 Umair Afzal 11/7/2016
如果我们的单元格中有一个按钮怎么办?
0赞 Weston Mitchell 7/1/2021
tableView.allowsSelection = NO;不允许在单元格内点击按钮......从那以后有什么变化吗?我知道这篇文章很旧
0赞 JosephH 7/2/2021
@WestonAMitchell 您可能想查看以“如果您的单元格中有需要单击的按钮”开头的句子。您需要使用 setSelectionStyle 解决方案。
0赞 Weston Mitchell 7/2/2021
@JosephH我已经有那一套了。我实际上发现我的问题是我使用 UITableViewCell 来设置其按钮的约束,而我应该使用 self.contentView。此外,还要确保所有视图都从contentView的顶部到底部进行垂直约束。self
366赞 mbm29414 6/10/2011 #6

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



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

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

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

当我在 UITableViewCell 中托管 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.To 对整个表格执行此操作,可以将上述解决方案应用于表格中的每个单元格,但也可以这样做:

[tableView setAllowsSelection:NO];

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


3.To 将单元格设置为“只读”,您可以简单地执行以下操作:

[cell setUserInteractionEnabled:NO];



4.To 将整个表设置为“只读”

[tableView setUserInteractionEnabled:NO];



5.To 即时确定是否突出显示单元格(根据此答案隐式包括选择),可以实现以下协议方法:UITableViewDelegate

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

评论

3赞 lilbyrdie 6/11/2011
如果从笔尖加载单元设计,则复选框(IB 中)将适用于 #3(以及 #4 的表)。对于 #4 与 #2,单元内的控件是否具有交互性是否有区别?
4赞 mbm29414 6/11/2011
是的。如果您想禁用选择但允许 UIButtons 等...若要继续支持用户交互,请使用 #2。如果您想要一个完全只读的单元格,请使用 #4。当然,为什么在非交互式单元格中除了 UIViews 或 UILabels 之外还有任何东西,这超出了我的范围。也许有人想在发生其他事情时禁用所有交互。
10赞 simon 4/9/2014
#4 是一个糟糕的主意,这样做也会禁用表格视图中的滚动
4赞 mbm29414 4/10/2014
@simon 实际上,这并不是一个可怕的主意;根据您的情况,这是一个选项,可能是也可能不是一个好的选择。此外,#4 禁用 USER 滚动;如有必要,您仍然可以实现自己的。我同意 #4 没有多大用处,但这并不是一个糟糕的主意。
3赞 Benjohn 7/21/2015
为了完整起见,请您为 tableView:shouldHighlightRowAtIndexPath: 添加一个大声疾呼,这通常是(并非总是)我的首选方法。
11赞 iDhaval 3/24/2012 #7

我们可以编写如下代码

 cell.selectionStyle = UITableViewCellSelectionStyleNone;

但是当我们在行上方有自定义单元格 xib,此时会发出警告

定制细胞 XIB

我们需要从界面构建器中设置选择样式 None

8赞 v_1 7/9/2012 #8

试试这个

cell.selectionStyle = UITableViewCellSelectionStyleNone;

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

您还可以使用InterfaceBuilder设置选择样式。

60赞 cbowns 11/1/2012 #9

从 iOS 6.0 开始,具有 .(在 iOS 文档中阅读相关内容。UITableViewDelegatetableView:shouldHighlightRowAtIndexPath:

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

评论

2赞 beebcon 5/6/2016
偶然发现了这个线程,我很震惊地看到这个线程之前还有这么多其他答案。这无疑是正确的方法。
2赞 mattyohe 6/10/2016
这确实是应该考虑的正确和唯一的答案。任何其他提及 userInteraction 的内容都是完全不正确的。
36赞 Chris Fox 11/13/2012 #10

如果希望选择只闪烁,而不保持选中状态,可以调用,在

didSelectRowAtIndexPath

以下

[tableView deselectRowAtIndexPath:indexPath animated:YES];

因此,它将闪烁所选状态并恢复。

评论

3赞 VinceFior 9/3/2015
使用这种方法,该行会立即突出显示,然后在半秒内淡出。这就是 Apple 设置菜单的样式,所以对我来说看起来不错。
4赞 Aniruddh 12/17/2012 #11

更好的方法是:

cell.userInteractionEnabled = NO;

此方法不会调用 method。didSelectRowAtIndexPath:

14赞 Yarek T 1/4/2013 #12

我也一直在与此作斗争,对我禁止使用财产进行了控制。我有一个 3 个单元格的静态设置表,其中 2 个带有日期,1 个带有开/关开关。在 Storyboard/IB 中玩过之后,我设法使底部的一个不可选择,但是当您点击它时,顶部一行的选择就会消失。下面是我的设置 UITableView 的 WIP 图像:UITableViewCelluserInteractionEnabled

Settings UITableView

如果您点击第 3 行,则没有任何反应,选择将保留在第二行。该功能实际上是 Apple 日历应用程序的添加事件时间选择屏幕的副本。

代码出奇地兼容,一直到 IOS2 =/:

- (NSIndexPath *)tableView: (UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row == 2) {
        return nil;
    }
    return indexPath;
}

这与将选择样式设置为无结合使用,因此单元格不会在触地事件时闪烁

6赞 Sharme 1/18/2013 #13

禁用 UItableviewcell 的突出显示

cell.selectionStyle = UITableViewCellSelectionStyleNone;

并且不应允许用户与单元格进行交互。

cell.userInteractionEnabled = NO;
2赞 ashevin 4/25/2013 #14

至少从 iOS 6 开始,您可以覆盖自定义单元格中的方法以防止蓝色突出显示。不会禁用或影响其他交互。必须覆盖所有三个。

- (void) setHighlighted:(BOOL)highlighted
{
}

- (void) setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
}

- (void) setSelected:(BOOL)selected animated:(BOOL)animated
{
}
52赞 vignesh kumar 4/25/2013 #15

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

UITableView Inspector

评论

2赞 Itai Spector 7/11/2016
最佳解决方案恕我直言
1赞 Bogdan Evsenev 1/18/2017
我经常使用这个解决方案
5赞 iEinstein 5/10/2013 #16

您可以使用此

cell.selectionStyle = UITableViewCellSelectionStyleNone;
7赞 Steve Barden 8/21/2013 #17

虽然这是防止行在选择过程中显示突出显示的最佳和最简单的解决方案

cell.selectionStyle = UITableViewCellSelectionStyleNone;

我还想建议,偶尔简要显示该行已被选中,然后将其关闭是有用的。这会提醒用户确认他们打算选择的内容:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
     [tableView deselectRowAtIndexPath:indexPath animated:NO];
...
}
5赞 Harini 8/25/2013 #18

最好的解决方案是将选择样式设为无

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

但是,这里我们考虑的是,没有用于选定状态的自定义图像。

5赞 Mak083 10/8/2013 #19

您可以使用....

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
6赞 virindh 1/14/2014 #20

您也可以将背景颜色设置为 Clear 以达到与 相同的效果,以防您不想/不能使用 。UITableViewCellSelectionStyleNoneUITableViewCellSelectionStyleNone

您将使用如下代码:

UIView *backgroundColorView = [[UIView alloc] init];
backgroundColorView.backgroundColor = [UIColor clearColor];
backgroundColorView.layer.masksToBounds = YES;
[cell setSelectedBackgroundView: backgroundColorView];

这可能会降低您的性能,因为您为每个单元格添加了额外的彩色视图。

6赞 iDeveloper 4/10/2014 #21
cell.selectionStyle = UITableViewCellSelectionStyleNone;
6赞 Programming Learner 7/12/2014 #22

您可以使用:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

在 UITableView 的索引路径方法的行单元格中。

您也可以使用:

[tableView deselectRowAtIndexPath:indexPath animated:NO];

在 TableView 中,didselectrowatindexpath 方法。

评论

0赞 Dan 1/25/2018
它现在在 Swift 3 中。cell.selectionStyle = UITableViewCellSelectionStyle.none
5赞 Rinku Sadhwani 7/31/2014 #23
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell setSelected:NO animated:NO];
[cell setHighlighted:NO animated:NO];

快乐的编码!!

21赞 Arun Gupta 11/22/2014 #24

目标-C:

  1. 下面的代码片段禁用突出显示,但它也禁用对 .因此,如果您不实施,请使用以下方法。这应该在创建表时添加。不过,这将适用于按钮和单元格内部。didSelectRowAtIndexPathdidSelectRowAtIndexPathUITextField

    self.tableView.allowsSelection = NO;
    
  2. 下面的代码片段禁用突出显示,并且不会禁用对 .将单元格的选择样式设置为“无”didSelectRowAtIndexPathcellForRowAtIndexPath

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
  3. 下面的代码片段禁用单元格上的所有内容。这将禁用与 , 的交互:buttonstextfields

    self.tableView.userInteractionEnabled = false;
    

迅速:

以下是上述解决方案的等效项:SwiftObjective-C

  1. 替换第一种溶液

    self.tableView.allowsSelection = false
    
  2. 更换第二种溶液

    cell?.selectionStyle = UITableViewCellSelectionStyle.None
    
  3. 替代第三种溶液

    self.tableView.userInteractionEnabled = false
    
40赞 Aks 12/2/2014 #25

编辑:对于较新的Swift,它更改为:

cell.selectionStyle = .none

有关详细信息,请参阅以下内容: https://developer.apple.com/documentation/uikit/uitableviewcell/selectionstyle

如果有人需要 Swift 的答案:

cell.selectionStyle = .None

评论

1赞 bably 9/9/2015
我们也可以使用这个 cell.selectionStyle = UITableViewCellSelectionStyle.None
6赞 Cindy 12/4/2014 #26

您也可以从情节提要中执行此操作。单击表视图单元格,然后在属性检查器中的“表视图单元格”下,将“所选内容”旁边的下拉列表更改为“无”。

5赞 Zorayr 2/19/2015 #27

带自定义单元格的 Swift 解决方案:

import Foundation

class CustomTableViewCell: UITableViewCell
{
  required init(coder aDecoder: NSCoder)
  {
    fatalError("init(coder:) has not been implemented")
  }

  override init(style: UITableViewCellStyle, reuseIdentifier: String?)
  {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    self.selectionStyle = UITableViewCellSelectionStyle.None
  } 
}
29赞 parvind 3/30/2015 #28

1- 您所要做的就是使用以下任一方法在 UITableViewCell 实例上设置选择样式


目标-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];


斯威夫特 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None


斯威夫特 3:

cell.selectionStyle = .none


2 - 不要在表视图中实现 -tableView:didSelectRowAtIndexPath:,或者显式排除您希望不执行任何操作的单元格(如果确实实现了它)。delegate

3 - 此外,您也可以从故事板中执行此操作。单击表视图单元格,然后在属性检查器中的“表视图单元格”下,将“所选内容”旁边的下拉列表更改为“无”。


4 - 您可以在 (iOS) Xcode 9 , Swift 4.0 中使用以下代码禁用表格单元格突出显示

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let cell = tableView.dequeueReusableCell(withIdentifier: "OpenTbCell") as! OpenTbCell
        cell.selectionStyle = .none
        return cell


}
31赞 Ahsan Ebrahim Khatri 3/30/2015 #29

这是我在编写这段代码时使用的:cellForRowAtIndexPath

cell.selectionStyle = UITableViewCellSelectionStyleNone;
5赞 Jayprakash Dubey 5/15/2015 #30

可以使用 UITableViewCell 的 selectionStyle 属性

 cell.selectionStyle = UITableViewCellSelectionStyleNone;

 [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

另外,不要实现以下委托

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

如果您已经创建了 Xib/Storyboard 文件,则可以通过取消选中 tableview 的 setUserInteractionEnabled 属性将其更改为 No。 这将使您的表视图变为只读。

10赞 priyanka gautam 10/19/2015 #31

我正在使用它,这对我有用。

cell?.selectionStyle = UITableViewCellSelectionStyle.None
11赞 Gaurav Patel 5/18/2016 #32

你只需要把这段代码放到cellForRowAtIndexPath中

要禁用单元格的选择属性:(点击单元格时)。

cell.selectionStyle = UITableViewCellSelectionStyle.None

评论

0赞 Darko 8/30/2016
谢谢,我的单元格中有一张图片,上面有一个标签。我已经设置了标签背景,但每次单击背景都会消失,这已经解决了它。
38赞 Mohammad Zaid - LushBinary.com 10/5/2016 #33

XIB 的 Attribute Inspector 中,将值设置为 。UITableViewCellSelectionNone

enter image description here

评论

0赞 Timothy Tripp 1/20/2017
这正是我所需要的。我仍然想要didSelect...通知,但没有可见的选择指示。谢谢!
49赞 MANISH PATHAK 1/8/2017 #34

SWIFT 3 的固定解决方案

cell.selectionStyle = .none
8赞 Kamani Jasmin 4/14/2018 #35

直接禁用 TableViewCell 在情节提要中的突出显示

enter image description here

3赞 Praful Argiddi 9/14/2018 #36

您可以在 (iOS) Xcode 9 , Swift 4.0 中使用以下代码禁用表格单元格突出显示

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let cell = tableView.dequeueReusableCell(withIdentifier: "OpenTbCell") as! OpenTbCell
        cell.selectionStyle = .none
        return cell


}
2赞 vrat2801 7/25/2019 #37

方案 - 1

如果您不想在表格视图上选择某些特定单元格,则可以在cellForRow函数中为这些单元格设置选择样式。

Objective-C语言

cell.selectionStyle = UITableViewCellSelectionStyleNone;

斯威夫特 4.2

cell.selectionStyle = .none

方案 - 2

要禁用整个表视图上的选择:

Objective-C语言

self.tableView.allowsSelection = false;

斯威夫特 4.2

self.tableView.allowsSelection = false
1赞 Muhammad Ahmad 7/30/2019 #38

非常简单的东西。在返回 tableview 单元格之前,请使用表视图单元格的 style 属性。

只需在返回表视图单元格之前编写此代码行即可
cell.selectionStyle = .none

11赞 Abdul Karim Khan 1/15/2020 #39

UITableViewDataSource 协议中,在方法中添加:cellForRowAt

let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR_CELL_IDENTIFIER", for: indexPath)                
cell.selectionStyle = .none
return cell

您可以转到“情节提要”>“选择单元格”>“身份检查器”>“选择”,然后从下拉列表中选择“无”。

20赞 Rashid Latif 8/10/2020 #40

斯威夫特 3、4 和 5

更好的做法,编写代码UITableViewCell

例如,您有名称 , 在只是写UITableViewCellMyCellawakeFromNibself.selectionStyle = .none

完整示例:

class MyCell: UITableViewCell {
    
    override func awakeFromNib() {
        super.awakeFromNib()
        self.selectionStyle = .none
    }
    
}
7赞 testing 10/21/2020 #41

禁用 UITableView 中所有 UITableViewCell 的选择

tableView.allowsSelection = false

禁用特定 UITableViewCells 的选择

cell.selectionStyle = UITableViewCell.SelectionStyle.none
6赞 André Herculano 6/15/2021 #42

我已经浏览了所有答案,对我的用例有效的方法如下:

tableView.allowSelection = false
public func tableView(_ tableView: UITableView, canFocusRowAt indexPath: IndexPath) -> Bool {
    true
}

这样,表格保持可聚焦,用户可以滚动浏览其元素,但无法“按下/选择”它们。

只需设置即可选择列表元素(只是不要留下灰色选择标记)。仅仅设置会导致我的桌子无法聚焦。用户将无法滚动浏览元素。cell.selectionStyle = .noneallowSelection = false