【问题标题】:How can I disable the UITableView selection?如何禁用 UITableView 选择?
【发布时间】:2010-09-16 11:53:59
【问题描述】:

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

【问题讨论】:

  • 原始问题的标题不好。 OP 主要希望禁用selection,当然highlighting 会因此而被禁用。许多高票的答案解释了如何disable selection 并且没有解决禁用highlighting 的问题。要仅禁用突出显示,请使用 cell.selectionStyle = .None 或转到 storyboard / cell / Selection = None
  • 请更新标题或帖子。我糊涂了。基于这个问题,我不知道提供的答案是什么意思。

标签: ios uitableview cocoa-touch


【解决方案1】:

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

目标-C:

cell.selectionStyle = UITableViewCellSelectionStyleNone;

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

斯威夫特 2:

cell.selectionStyle = UITableViewCellSelectionStyle.None

Swift 3 和 4.x:

cell.selectionStyle = .none

此外,请确保您要么不在表格视图委托中实现-tableView:didSelectRowAtIndexPath:,要么明确排除您不希望在实现时不采取任何行动的单元格。

More info herehere

【讨论】:

  • @Tony 如果您在单元格中有 UITextField,那是个坏主意。
  • @TonyMillion 如果您想使用内置编辑控件(例如滑动删除),这也是一个坏主意。如果将 userInteractionEnabled 设置为 NO,则删除按钮不会响应用户触摸事件。
  • 到此线程较晚,但使用 cell.allowsSelection 代替 userInteraction。这会停止单元格的交互方法,但不会阻止常规 UIView 响应程序的内容。
  • 设置 cell.userInteractionEnable=No 不会停止触发 didSelectRowAtIndexPath。
  • 我会投票赞成答案,但为了清楚起见,OP 只要求禁用“突出显示”,没有禁用整个单元格交互,所以所有这些 cmets 都是题外话。
【解决方案2】:

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

tableView.allowsSelection = false

这意味着didSelectRowAt# 根本不起作用。也就是说,触摸表格的一行,这样,绝对不会做任何事情。 (因此,很明显,永远不会有选定的动画。)

(请注意,如果在单元格上,您有 UIButton 或任何其他控件,当然这些控件仍然可以工作。您碰巧在表格单元格上拥有的任何控件都与 UITableView 允许您的能力完全无关使用didSelectRowAt#“选择一行”。)

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

tableView.allowsSelectionDuringEditing = false 

【讨论】:

  • 这终于对我有用,我尝试使用 cell.selectionStyle = UITableViewCellSelectionStyleNone;但它没有用。需要注意的一件事:应该是:tableView.allowsSelection = NO;不假。
  • 我认为,这是最好的选择。单元格上的按钮是活动的,但文本是不活动的。
  • 这是如何被接受的答案并且有这么多赞成票?它根本没有回答这个问题!您需要在单元格上设置selectionStyle 属性:在Swift 中为cell.selectionStyle = UITableViewCellSelectionStyle.None,在Objective-C 中为cell.selectionStyle = UITableViewCellSelectionStyleNone
  • 这在 swift 2 中对我有用。tableView.allowSelection = false
  • 根据需要有几种方法可以做到这一点。没有选择样式和没有选择都可以工作,或者都失败。这是一个例子。如果要选择单元格并调用 tableViewDidSelectRowAtIndexPath,则需要 cell.selectionStyle = .None。如果您不想或不关心调用该委托函数(即在 tableViewCell 中有一个文本字段)设置 tableView.allowsSelection = false 就可以了。
【解决方案3】:

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



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

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

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

[tableView setAllowsSelection:NO];

在我的测试中,这仍然允许UITableViewCell 中的控件进行交互。


3.要使单元格“只读”,您可以这样做:

[cell setUserInteractionEnabled:NO];



4.使整个表格“只读”

[tableView setUserInteractionEnabled:NO];



5.动态判断是否高亮单元格(根据this answer隐含选择),可以实现如下UITableViewDelegate协议方法:

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

【讨论】:

  • 如果您从笔尖加载单元设计,则复选框(在 IB 中)对于 #3(以及在 #4 的表上)将正常工作。对于 #4 和 #2,单元格内的控件是否交互有区别吗?
  • 是的。如果您想禁用选择但允许 UIButtons 等...继续支持用户交互,请使用 #2。如果您想要一个完全只读的单元格,请使用#4。当然,为什么在非交互式单元格中除了 UIViews 或 UILabels 之外还有其他内容,这超出了我的理解。也许有人想在其他事情发生时禁用所有交互。
  • #4 是个糟糕的主意,这样做也会禁用表格视图中的滚动
  • @simon 实际上,这不是一个糟糕的主意。根据您的情况,这是一个可能是也可能不是一个好选择的选项。此外,#4 禁用 USER 滚动;如有必要,您仍然可以实现自己的。我同意 #4 没有多大用处,但这不是一个糟糕的主意。
  • 为了完整起见,您能否为tableView:shouldHighlightRowAtIndexPath:添加一个大喊大叫,这是通常(并非总是)我的首选方法。
【解决方案4】:

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

如果您只想禁用部分单元格的选择,请使用:

cell.userInteractionEnabled = NO;

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

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

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

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

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

tableView.allowsSelection = NO;

(感谢 Paulo De Barros,谢谢!)

【讨论】:

  • 如果我们的单元格中有一个按钮会怎样?
  • tableView.allowsSelection = NO; 不允许在单元格内单击按钮...从那以后有什么变化吗?我知道这篇文章很旧
  • @WestonAMitchell 您可能想查看以“如果您的单元格中有需要单击的按钮”开头的句子。您需要使用 setSelectionStyle 解决方案。
  • @JosephH 我已经有了那套。我实际上发现我的问题是我的约束使用 UITableViewCell 的self 来设置其按钮的约束,而我应该一直使用 self.contentView。还要确保所有视图都从 contentView 的顶部垂直限制到底部。
【解决方案5】:

从 iOS 6.0 开始,UITableViewDelegate 具有 tableView:shouldHighlightRowAtIndexPath:。 (在 iOS Documentation 中了解它。)

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

【讨论】:

  • 偶然发现了这个帖子,在这个帖子之前看到这么多其他答案,我很震惊。这无疑是正确的方法。
  • 这确实是正确且唯一应该考虑的答案。任何其他提及 userInteraction 的内容都是完全错误的。
【解决方案6】:

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

【讨论】:

  • 最佳解决方案恕我直言
  • 我经常用这个方案
【解决方案7】:

SWIFT 3 的固定解决方案

cell.selectionStyle = .none

【讨论】:

    【解决方案8】:

    在属性检查器中UITableViewCellXIB 中将Selection 的值设置为None

    【讨论】:

    • 这正是我所需要的。我仍然想要 didSelect... 通知,但没有可见的选择指示。谢谢!
    【解决方案9】:

    如果有人需要回答Swift:

    cell.selectionStyle = .None
    

    【讨论】:

    • 我们也可以使用这个 cell.selectionStyle = UITableViewCellSelectionStyle.None
    【解决方案10】:

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

    didSelectRowAtIndexPath
    

    以下

    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    

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

    【讨论】:

    • 使用这种方法,该行会立即突出显示,然后在半秒内淡出。这就是 Apple 设置设置菜单的样式,所以我觉得很好。
    【解决方案11】:

    这是我用的,在cellForRowAtIndexPath写下这段代码:

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    

    【讨论】:

      【解决方案12】:

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

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

      【讨论】:

      • 我不喜欢这种方法,因为它仍然会以突出显示的状态显示单元格,直到修改为止。
      • 这正是我喜欢它的原因:-)
      【解决方案13】:

      1- 您所要做的就是在UITableViewCell 实例上设置选择样式:


      目标-C:

      cell.selectionStyle = UITableViewCellSelectionStyleNone;
      

      [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
      


      斯威夫特 2:

      cell.selectionStyle = UITableViewCellSelectionStyle.None
      


      斯威夫特 3:

      cell.selectionStyle = .none
      


      2 - 不要在您的表格视图delegate 中实现 -tableView:didSelectRowAtIndexPath: 或明确排除您不希望执行的单元格。

      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
      
      
      }
      

      【讨论】:

        【解决方案14】:

        目标-C:

        1. 在 sn-p 下面禁用突出显示,但它也禁用对 didSelectRowAtIndexPath 的调用。因此,如果您没有实现didSelectRowAtIndexPath,请使用以下方法。这应该在您创建表时添加。不过,这将适用于单元格内的按钮和UITextField

          self.tableView.allowsSelection = NO;
          
        2. 在 sn-p 下面禁用突出显示,它不会禁用对 didSelectRowAtIndexPath 的调用。在cellForRowAtIndexPath中设置单元格的选择样式为None

          cell.selectionStyle = UITableViewCellSelectionStyleNone;
          
        3. 在 sn-p 下面禁用单元格上的所有内容。这将禁用与buttonstextfields 的交互:

          self.tableView.userInteractionEnabled = false;
          

        斯威夫特:

        以下是Swift 等效于上述Objective-C 的解决方案:

        1. 替换第一个解决方案

          self.tableView.allowsSelection = false
          
        2. 更换第二个解决方案

          cell?.selectionStyle = UITableViewCellSelectionStyle.None
          
        3. 替换第三种解决方案

          self.tableView.userInteractionEnabled = false
          

        【讨论】:

          【解决方案15】:

          尝试输入:

          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)
          }
          

          【讨论】:

            【解决方案16】:

            我也一直在努力解决这个问题,在我的UITableViewCell 中有一个控件禁止使用userInteractionEnabled 属性。我有一个用于设置的 3 单元静态表,2 个带日期,1 个带开/关开关。在 Storyboard/IB 中玩过之后,我设法使底部的一个不可选择,但是当您点击它时,顶部行之一的选择消失了。这是我的设置 UITableView 的 WIP 图像:

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

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

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

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

            【讨论】:

              【解决方案17】:

              我们可以这样写代码

               cell.selectionStyle = UITableViewCellSelectionStyleNone;
              

              但是当我们在 give warning 行上方有 custom cell xib

              自定义单元格xib

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

              【讨论】:

                【解决方案18】:

                您只需将此代码放入 cellForRowAtIndexPath

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

                cell.selectionStyle = UITableViewCellSelectionStyle.None
                

                【讨论】:

                • 谢谢,我的单元格中有一张图片,上面有一个标签。我已经设置了标签背景,但是每次我点击背景都会消失,这已经解决了。
                【解决方案19】:

                试试这个

                cell.selectionStyle = UITableViewCellSelectionStyleNone;
                

                [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
                

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

                【讨论】:

                  【解决方案20】:

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

                  cell?.selectionStyle = UITableViewCellSelectionStyle.None
                  

                  【讨论】:

                    【解决方案21】:

                    Swift 3,4 和 5

                    更好的做法,在UITableViewCell写代码

                    例如,您有名为MyCellUITableViewCell, 在awakeFromNibself.selectionStyle = .none

                    完整示例:

                    class MyCell: UITableViewCell {
                        
                        override func awakeFromNib() {
                            super.awakeFromNib()
                            self.selectionStyle = .none
                        }
                        
                    }
                    

                    【讨论】:

                      【解决方案22】:

                      来自 UITableViewDataSource 协议,方法内部cellForRowAt 添加:

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

                      您可以转到 Storyboard > Select Cell > Identity Inspector > Selection 并从下拉列表中选择无。

                      【讨论】:

                        【解决方案23】:

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

                        cell.selectionStyle = UITableViewCellSelectionStyleNone;
                        

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

                        - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
                             [tableView deselectRowAtIndexPath:indexPath animated:NO];
                        ...
                        }
                        

                        【讨论】:

                          【解决方案24】:

                          在情节提要中直接禁用 TableViewCell 高亮

                          【讨论】:

                            【解决方案25】:

                            禁用 UItableviewcell 的突出显示

                            cell.selectionStyle = UITableViewCellSelectionStyleNone;
                            

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

                            cell.userInteractionEnabled = NO;
                            

                            【讨论】:

                              【解决方案26】:

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

                              您将使用如下代码:

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

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

                              【讨论】:

                                【解决方案27】:

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

                                【讨论】:

                                  【解决方案28】:

                                  您可以使用:

                                  cell.selectionStyle = UITableViewCellSelectionStyleNone;
                                  

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

                                  你也可以使用:

                                  [tableView deselectRowAtIndexPath:indexPath animated:NO];
                                  

                                  在tableview中didselectrowatindexpath方法。

                                  【讨论】:

                                  • 现在是 Swift 3 中的 cell.selectionStyle = UITableViewCellSelectionStyle.none
                                  【解决方案29】:

                                  你可以用这个

                                  cell.selectionStyle = UITableViewCellSelectionStyleNone;
                                  

                                  【讨论】:

                                    【解决方案30】:

                                    你可以使用 ....

                                    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
                                    

                                    【讨论】:

                                      猜你喜欢
                                      • 1970-01-01
                                      • 2011-01-17
                                      • 2011-08-02
                                      • 2022-01-15
                                      • 2013-05-10
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 1970-01-01
                                      相关资源
                                      最近更新 更多