【问题标题】:-didSelectRowAtIndexPath: not being called-didSelectRowAtIndexPath:未被调用
【发布时间】:2010-09-20 08:00:36
【问题描述】:

我正在编写一个在选项卡视图中带有表格视图的 iOS 应用程序。在我的UITableViewController 中,我实现了-tableView:didSelectRowAtIndexPath:,但是当我在运行时选择一行时,没有调用该方法。但是表格视图正在被填充,所以我知道我的控制器中的其他 tableView 方法正在被调用。

有没有人知道我为了实现这一点而搞砸了什么?

【问题讨论】:

  • 你也可能在 UITableView 顶部有一个gestureRecognizer,它吸收了选择..(可能性之一)
  • 如果正在填充表格视图,请小心,这意味着数据源设置正确。选择是委托方法的一部分。所以也许 DataSource 设置得很好,但 Delegate 没有!
  • 嗨,M.Othman,您的评论正是我自己的问题的问题所在。你知道如何让gestureRecognizer“与”UITableView一起工作吗?
  • 我注意到,如果我点击并按住,点击最终会调用-didSelectRowAtIndexPath。我想出了帽子,因为我在 tableview 上有一个点击手势识别器,并且手势必须先失败,然后才能接收到触摸。虽然奇怪的是表格选择动画不受手势识别器的影响。
  • 我在这里遇到了同样的问题,并且有幸了解到您不能在 UITableView 之上使用手势识别器。谢谢 M. Othman!

标签: ios uitableview cocoa-touch didselectrowatindexpath


【解决方案1】:

就我而言,我在加载时动态计算TableViewSuperView 的高度。由于计算错误,TableView 位于SuperView 之外。 TableView 画得很好,但是所有交互都被禁用(并且从未调用过didSelectRowAtIndexPath)。很难检测到,因为没有视觉迹象表明 TableView 不可“访问”。

【讨论】:

    【解决方案2】:

    我不能评论,写在这里。 在我的情况下didSelectRow 有效,但不是didDeselectRow。 我将delegatedataSource 设置为tableView,这解决了我的问题。

    【讨论】:

      【解决方案3】:

      在我的情况下,只有一个单元有这个问题。该单元格包括处于只读模式的 UITextView 插座。虽然在点击之前它是只读的。敲击后,键盘升起。事实证明,它仍然需要禁用交互。

      cell.content.scrollEnabled = NO;
      cell.content.editable = NO;
      cell.content.userInteractionEnabled = NO;
      cell.content.delegate = nil;
      

      [cell.content resignFirstResponder];

      【讨论】:

        【解决方案4】:

        我刚刚遇到了这个问题,但它并没有立即发生;选择几个单元格后,他们将停止调用didSelectItemAtIndexPath。我意识到问题在于集合视图将allowsMultipleSelection 设置为TRUE。因为单元格永远不会被取消选择,所以这会阻止未来调用didSelectItemAtIndexPath

        【讨论】:

          【解决方案5】:

          如果UITapGestureRecognizer 出现问题,您可以解决此问题:

          • 在情节提要中:

          在带有Objective-C的代码中:

          UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; 
          [self.view addGestureRecognizer:tap];
          
          [tap setCancelsTouchesInView:NO];
          

          在带有Swift的代码中:

          let tap = UITapGestureRecognizer(target: self, action:Selector("dismissKeyboard"))
          view.addGestureRecognizer(tap)
          
          tap.cancelsTouchesInView = false
          

          【讨论】:

            【解决方案6】:

            确保您实现了tableView:didSelectRowAtIndexPath 而不是tableView:didDeSelectRowAtIndexPath

            这让我有好几次!

            【讨论】:

              【解决方案7】:

              我间歇性地遇到这个问题。有时触摸一个单元格会导致它被选中。有时它不会收到触摸事件。

              我正在使用 ios8 中引入的一项功能,称为自调整单元格。我遇到了这个blog post,它指出:

              第一次显示表格视图时,您可能会发现一些单元格 尺寸不合适。但是当你滚动表格视图时,新的 单元格以正确的行高显示。要解决此问题, 您可以在视图出现后强制重新加载:

              override func viewDidAppear(animated: Bool) {
                  tableView.reloadData()
              }
              

              这为我解决了这个问题。即使表格视图正确呈现,触摸处理(特别是 UITableView 的 hitTest)似乎也受到上述错误的影响。

              【讨论】:

                【解决方案8】:

                我重复了所有以前的答案,但没有一个对我有帮助。经过反复试验,我找到了不同的解决方案。我有一个 UIImageView 覆盖整个单元格(作为背景)。默认情况下 UIImageView 禁用用户交互。通过启用 imageviews 用户交互委托方法 -didSelectRowAtIndexPath: 再次被调用。 例如。

                cell.imgView.userInteractionEnabled = YES;
                

                【讨论】:

                  【解决方案9】:

                  对于 Xcode 6.4,Swift 1.2 。选择“标签”已在 IB 中更改。我不知道如何以及为什么。将其设置为“单选”使我的表格视图单元格再次可选择。

                  【讨论】:

                    【解决方案10】:

                    就我而言,问题是我有一个UITableViewCell 子类,并且我实现了这两种方法: touchesBegan:withEvent: & touchesEnded:withEvent 处理精美的触摸动画。 但是我忘记添加 [super touchesBegan:touches withEvent:event]; 方法广告 [super touchesEnded:touches withEvent:event]; 来通知单元格的父级。

                    因此将代码更改为以下解决了我的问题:

                    -(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
                        [super touchesBegan:touches withEvent:event];
                        //blah blah blah
                    }
                    
                    -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
                        [super touchesEnded:touches withEvent:event];
                        //rest of the code
                    }
                    

                    【讨论】:

                    • 可以确认这特别对我造成了 OP 的问题
                    【解决方案11】:

                    如果您在 UITableView 顶部添加了一个手势识别器,didSelectRowAtIndexPath 将不会被调用。

                    所以你需要使用gestureRecognizer委托方法来避免在特定视图中触摸。

                    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
                        if ([touch.view isDescendantOfView:YourTable]) {
                            return NO;
                        }
                        return YES;
                    }
                    

                    【讨论】:

                    • if ([touch.view isDescendantOfView:YourTable])
                    【解决方案12】:

                    这篇文章中有一些惊人的线索和答案(也许是我见过的最好的讨论之一!)这里的线索帮助我弄清楚我的问题是什么,但我仍然花了很多时间在我的键盘上流口水尝试发现问题,这与其他帖子类似。但是,我最终发现它的方式有点不同,所以我想分享一下以防其他人也遇到它。

                    原来我的问题是,在代码中,超类添加了一个全屏“错误视图”,它不是隐藏的,而是透明的。但是,因为它在 tableview 上并且“用户操作”设置为 YES,所以它拦截了我对 tableview 的触摸。

                    我使用 Xcode 很酷的“Debug View Hierarchy”按钮对此进行了诊断。这是一个带有注释的屏幕截图,希望能解释我做了什么以及我最终如何诊断出这个问题。

                    在代码中,我只需要这样做:

                    errorMessageView.setUserInteractionEnabled = NO;
                    // or
                    errorMessageView.hidden = YES;
                    

                    【讨论】:

                    • 我的情况类似。正在接收点击事件的全屏“点击视图”。即使删除点击手势识别器也没有解决它,因为“点击视图”在 Z 顺序中高于我的表格视图。我将“点击视图”移到表格视图下方,问题已解决。
                    【解决方案13】:

                    如果您的表格视图处于编辑模式(例如[tableView setEditing:YES animated:NO];),您需要设置tableView.allowsSelectionDuringEditing = YES;

                    【讨论】:

                      【解决方案14】:

                      您必须选择这些选项

                      但如果你想让UITableView在点击时不突出显示,那么你应该在UITableViewCell属性中进行更改。

                      选择无选项,如下所示

                      【讨论】:

                        【解决方案15】:
                        1. 添加@interface ExampleViewController () <UITableViewDelegate, UITableViewDataSource>

                        2. 在情节提要中进行委托

                        1. 添加代码

                          - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
                              UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
                             NSString *cellText = cell.textLabel.text;
                          }
                          

                        【讨论】:

                          【解决方案16】:

                          在我的情况下,解决方案是在下面的函数中将 NO 更改为 YES。

                          iOS 9+

                          - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
                          {
                              return YES;
                          }
                          

                          【讨论】:

                          • 这也是我的问题。我有多个 tableView 实现,忘记在此方法中分隔两个 tableView。
                          【解决方案17】:

                          如果您正在单击的单元格被突出显示但该函数仍未被调用,请仔细检查您的函数签名。它应该是这样的:

                          override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
                          

                          【讨论】:

                          • 这正是我的情况,但签名是正确的。我无计可施
                          【解决方案18】:

                          我不确定是否有人滚动到足够远才能看到这个答案,但由于这是关于这个主题的最受欢迎的问题并且没有答案,所以我会添加它:

                          从 Xcode 9 / Swift 4 开始,所有 Objective-C 方法都应标记为 @objc。编译器在识别应该应用它的位置方面做了合理的工作,但是它没有弄清楚继承。例如:

                          class Delegate: NSObject, UITableViewDelegate {
                          }
                          
                          class SuperDelegate: Delegate {
                              override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
                          }
                          

                          这不会产生任何警告、崩溃或构建错误。但是,在您添加 @objc 之前,您的线路不会被调用:

                          @objc class SuperDelegate: Delegate {
                              override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { return indexPath }
                          }
                          

                          【讨论】:

                            【解决方案19】:

                            确保在主线程上调用reloadData。如果您从某种异步方法(例如:某种网络请求)调用该方法,表格视图可能会或可能不会正确响应(在某些情况下应用程序甚至可能崩溃)。

                            使用主线程代码块来执行reloadData 调用,如果调用是在某个其他方法块(您不确定)中进行的:

                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                [tableView reloadData];
                            }];
                            

                            【讨论】:

                              【解决方案20】:

                              检查你的viewController是否有以下方法:

                              - (BOOL) tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
                                  return NO;
                              }
                              

                              如果你返回“NO”,didSelectRow 将不会被调用

                              【讨论】:

                              • 我整个昨天都在试图解决这个问题。谢谢。
                              【解决方案21】:

                              在我的情况下,我犯了一个小错误是我分配的:

                              tableView.isUserInteractionEnabled = false
                              

                              应该是:

                              tableView.isUserInteractionEnabled = true
                              

                              【讨论】:

                                【解决方案22】:

                                我刚刚找到了另一种调用didSelect 方法的方法。在某些时候,在 func 声明本身出现一些错误时,XCode 建议我将 @nonobjc 添加到我的方法中:

                                @nonobjc func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

                                这将继续编译而不会抱怨,但您永远不会被 ui 操作调用。

                                “那是我的两分钱,我想要我的零钱回来”

                                【讨论】:

                                  【解决方案23】:

                                  在我的情况下,没有调用 didSelctRowAtIndexPath 是因为我在 tableView 的 Selection 属性中选择了 none,设置为 single selection解决了我的问题

                                  【讨论】:

                                    【解决方案24】:

                                    就我而言,问题在于将方法声明为私有。

                                    这不起作用:

                                    private func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                                    

                                    这行得通:

                                    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                                    

                                    【讨论】:

                                      【解决方案25】:

                                      我已阅读所有答案并非常同意。但在我的情况下完全不同。我的 detailViewController 有新的 segue 直接链接到 StoryBoard 中的 tableCell,这导致了这种情况。所以我不得不从我的单元格中删除那个segue并将它与UITableViewController本身链接起来。现在通过编写以下代码就可以了,

                                      override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                                              tableView.deselectRow(at: indexPath, animated: true)
                                              // Do any operation
                                              performSegue(withIdentifier: "DetailSegue", sender: self)
                                          }
                                      

                                      希望这个解决方案能帮助到那里的人!

                                      【讨论】:

                                        【解决方案26】:

                                        你必须检查这个 选择必须是单选,编辑必须在编辑期间没有选择 并且您还更改了 uttableviewcell 属性中的设置 您在表格视图单元格中编辑 样式必须是自定义的,标识符必须是 Rid 和部分是无

                                        【讨论】:

                                          【解决方案27】:

                                          请检查 UITapGestureRecognizer。 在我的情况下,为放置 tableview 的视图添加了 tapgesture,它正在像 didselect 一样吃掉 UITableview 的用户交互。 为视图禁用 Tapgesture 后,触发了 didselect 委托。

                                          【讨论】:

                                          • 这正是我的问题,在 ViewController 中使用 UITableView。
                                          【解决方案28】:
                                          tableView?.allowsSelection = true
                                          

                                          在 Xcode 11.7 中默认为 False

                                          【讨论】:

                                            【解决方案29】:

                                            当我的TableViewControllerclass nameInterface Builder 中设置不正确时,我遇到了这个问题。

                                            【讨论】:

                                              猜你喜欢
                                              • 2012-02-15
                                              • 1970-01-01
                                              • 1970-01-01
                                              • 1970-01-01
                                              • 2013-10-07
                                              • 1970-01-01
                                              • 1970-01-01
                                              相关资源
                                              最近更新 更多