-didSelectRowAtIndexPath:不被调用

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

有没有人知道我到底搞砸了什么才让这一切发生的?

222437 次浏览

听起来,这个类可能不是那个表视图的UITableViewDelegate,尽管UITableViewController应该自动设置它。

你是否有机会将委托重置为其他类?

在这种情况下,我遇到了两件事。

  1. 你可能忘了实现UITableViewDelegate协议,或者在你的类和你的表视图之间没有委托出口。

  2. 你可能有一个UIView在你的行里面,它是一个第一响应器,拿走你的点击。比如UIButton或类似的东西。

我知道是旧的,问题已经解决了,但有类似的问题,我认为问题是与我的自定义UITableViewCell,但解决方案是完全不同的-我重新启动XCode:),然后工作正常!就像Windows一样:)

我自己也有这个问题。我已经在IB中构建了视图的骨架(只是一个视图和一个TableView),委托没有设置。我把它连接到文件的所有者,它就像一个魅力。::保存::

我也有同样的问题。而且很难找到。但在我的代码中 是:< / p >
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}

它必须是return indexPath,否则不会调用-tableView:didSelectRowAtIndexPath:

好的,在这里更新,因为我刚刚遇到了这个问题,我的问题与这里发现的略有不同。

我在IB中查看,看到我的委托被设置,但它被错误地设置为视图,而不是文件的所有者(右键单击表视图,查看委托指向的位置)。

希望这能帮助到别人

我的问题不在上面。太差劲了。但我想我应该把它列在这里,也许它能帮助到别人。

我有一个tableViewController,它是我的“基”控制器,然后我创建了这个控制器的子类。我在“基”类的tableView:didSelectRowAtIndexPath例程中编写了所有代码。完全忘记在默认情况下,这个例程也已经在我的所有子类中创建了(尽管没有做任何事情的代码)。所以当我运行我的应用程序时,它运行了代码的子类版本,什么都不做,这让我很伤心。因此,当然,一旦我从子类中删除了例程,它使用mt“基”类例程,我就在业务中。

我知道。别笑。但也许这能帮别人省下我浪费的一小时…

如果你和我有同样的问题: 显然,如果tableView处于编辑模式,这个方法不会被调用。你必须设置allowsSelectionDuringEditing为true

通过这个问题:编辑时,' UITableView '不调用didSelectRowAtIndexPath ??

即使另一个答案已经被接受,我将为观察这个问题的人补充一个可能的问题和解决方案:

如果你打开了自动引用计数(ARC),你可能会发现即使你的控制器被分配为视图的委托,视图的消息也没有被接收到,因为ARC正在删除控制器。显然UITableView的委托指针不能算作ARC的引用,所以如果那是对它的唯一引用,控制器将被释放。你可以通过在控制器上实现dealloc方法并在那里设置断点或NSLog调用来验证这是否正在发生。

解决方案是在其他地方使用强引用跟踪控制器,直到确定不再需要它为止。

都是很好的答案,但还有一个需要注意……

(特别是当以编程方式创建UITableView时)

确保tableView可以通过设置[tableView setAllowsSelection:YES];或删除将其设置为NO的任何行来响应选择。

对此发表我的意见。

我有一个自定义UITableViewCell,有一个按钮覆盖整个单元格,所以当触摸发生时,按钮被选中,而不是单元格。

要么删除按钮,要么在我的情况下,我将按钮上的User interaction Enable设置为false,这样单元格就被选中了。

如果你看了这个,那么问题还是没有解决。

我有自定义单元格,其中复选框“启用用户交互”是禁用的。所以,我只要打开它。祝你好运。

以防有人和我犯同样愚蠢的错误

检查你所期望的didSelect的方法名是否会以某种方式意外地获得didDeselect。我花了大约两个小时才发现……

另一件可能导致问题的事情是不被选择的选择类型:

UITableView selection kind

正常选择应该是Single Selection应该是No Selection

要以编程方式做到这一点,请执行:

tableView.allowsSelection = YES

另一种可能性是UITapGestureRecognizer可以吃掉事件,就像这里的https://stackoverflow.com/a/9248827/214070一样

我没有怀疑这个原因,因为表格单元格仍然会突出显示蓝色,就像水龙头通过一样。

记住在viewDidLoad方法中设置数据源和委托,如下所示:

[self.tableView setDelegate:self];


[self.tableView setDataSource:self];

我有问题,控制不进入didselect行后应用断点。问题就在眼前。我从视图中删除了tab手势。那么它运行得很好

这可能只是在我的情况下,但我从备份中重新加载了一些文件,一些东西不能工作,包括这个。在做了完全清洁(产品>清洁或Shift +命令+ K)后,它工作了。可能是在预编译的头文件中搞砸了。这对你来说可能不是问题,但值得一试。

你可能犯的另一个错误(就像我犯的一样):如果你在单元格中设置segue, didSelectRowAtIndexPath将不会被调用。你应该在视图控制器中设置segue。

我遇到了一个问题,在几个月没有看我的代码后,我忘记了我实现了以下方法,由于一些不必要的需求

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

为了使行被选中,它应该返回YES。

另一个可能的原因似乎是UITableView嵌入在UIScrollView中。我今天遇到了这个问题,因为我无意中使用了滚动视图而不是普通视图作为控制器的根视图。

这些答案对我都没用。大约一个小时后,我发现了一件非常阴险的事情:

我在另一个表格视图的单元格中有一个表格视图。我决定创建一个包含内部表视图的封闭视图。我将这个视图命名为contentView并在xib中连接它。

UITableViewCell已经有一个contentView并对它做了一些奇怪的事情。当我将属性重命名为mainContentView并将视图重新连接到这个重命名的属性时,问题自行解决了。

我有个电话要打。userInteractionEnabled隐藏在一些定制表代码中。

大多数虫子都很蠢,不是吗?

我在我的表视图上放了一个UITapGestureRecognizer来消除键盘,这阻止了didSelectRowAtIndexPath:被调用。希望它能帮助到别人。

如果您有一个自定义单元格,请记住在Xib中(或通过代码)为单元格设置UserInteractionEnabled。

检查- hightforrowatindexpath是否不返回0。

另一个疯狂的可能性是:我在iPhone 5S上运行我的应用,我使用了:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

就像我过去一直做的那样。

然而,我没有仔细查看我的编译器警告…它说我应该把上面这一行改为:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

64位兼容性!摇动的拳头

当心,万一你开始扯你的头发。

注意故事板中的UITableView属性,在我的例子中发生的是,我在故事板中选择了combox为“Selection: Single Selection”,这不允许didSelectRowAtIndexPath方法运行。

我也有同样的问题,

原因是使用UITapGestureRecognizer。我想让键盘在我点击其他地方时消失。我意识到这覆盖了所有的点击动作,这就是为什么,didSelectRowAtIndexPath函数没有被调用。

当我注释与UITapGestureRecognizer相关的行时,它是有效的。此外,你可以检入UITapGestureRecognizer selector函数,如果被抽动的是UITableViewCell或不是。

我刚刚有了这个,就像过去发生在我身上的一样,它没有工作,因为我在尝试添加方法时没有注意自动补全,我实际上最终实现了tableView:didDeselectRowAtIndexPath:而不是tableView:didSelectRowAtIndexPath:

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

我不能评论,写在这里。 在我的情况下,didSelectRow工作,但不是didDeselectRow。 我设置delegatedataSourcetableView,这解决了我的情况

在我的例子中,只有一个细胞有这个问题。单元格以只读模式包含UITextView出口。虽然在点击前是只读的。一敲键盘,键盘就竖起来了。事实证明,它仍然需要禁用交互。

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

(细胞。内容resignFirstResponder);

我刚遇到这个问题,但它并没有马上发生;在选择几个单元格后,它们将停止调用didSelectItemAtIndexPath。我意识到问题是集合视图将allowsMultipleSelection设置为TRUE。由于单元格从未被取消选,这将阻止未来调用didSelectItemAtIndexPath

如果问题出现在UITapGestureRecognizer,你可以修复这个:

  • 在故事板:

enter image description here

在代码中使用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

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

这让我在很多场合!!

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

我使用的是ios8中引入的一个叫做自调整单元格的功能。我遇到了这个博客,指出:

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

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

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

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

对于Xcode 6.4, Swift 1.2。在IB中选择“标签”被改变了。我不知道是怎么改变的,为什么改变。将其设置为“单一选择”使我的表格视图单元格再次可选。enter image description here

在我的情况下,问题是我有一个UITableViewCell子类,我实现了这两个方法: touchesBegan:withEvent:,touchesEnded:withEvent处理一个花哨的动画触摸。 但是我忘记在[super touchesEnded:touches withEvent:event];中添加[super touchesBegan: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
}

如果你在UITableView上添加了一个gestureRecognizer, didSelectRowAtIndexPath将不会被调用。

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

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

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

事实证明,我的问题是,在代码中,一个超类添加了一个全屏的“错误视图”,它不是隐藏的,而是透明的。然而,因为它在tableview之上,“user action”被设置为YES,它拦截了我在tableview上的触摸。

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

在代码中,我只需要做:

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

Debug View Hierarchy .

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

您必须选择这些选项

enter image description here

但如果你想让__abc0在点击时不高亮显示,那么你应该改变UITableViewCell属性。

选择“选择”的“无”选项,如下所示

enter image description here

  1. 添加@interface ExampleViewController () <UITableViewDelegate, UITableViewDataSource>

  2. 在故事板中进行委托

enter image description here

  1. < p >添加代码

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

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

iOS 9 +

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

如果您所单击的单元格被突出显示,但函数仍然没有被调用,请再次检查函数的签名。它应该是这样的:

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

我不确定是否有人滚动到足够远的地方看到这个答案,但由于这是关于这个主题最受欢迎的问题,而答案并不在那里,我将添加它:

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

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

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

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

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

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

如果你返回"NO"didSelectRow不会被调用

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

tableView.isUserInteractionEnabled = false

它应该是:

tableView.isUserInteractionEnabled = true

我刚刚找到了另一种方法获得你的didSelect方法调用。在某种程度上,可能是在func声明本身的一些错误中,XCode建议我将@nonobjc添加到我的方法中:

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

这将继续编译没有抱怨,但你永远不会被ui动作调用。

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

在我的情况下,didSelctRowAtIndexPath不调用是因为我在tableView的选择属性中选择了没有一个,设置为单一的选择解决了我的问题

enter image description here

在我的例子中,问题是将方法声明为private。

这并没有起作用:

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

这工作:

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

我看了所有的答案,非常同意。但我的情况完全不同。我有新的segue为我的detailViewController直接链接到我的tableCell在StoryBoard导致这个。所以我必须从我的单元格中移除那个segue,并将它链接到UITableViewController本身。现在通过编写下面的代码,它可以工作,

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

希望这个解决方案能帮助到那些有困难的人!

你必须检查这个 选择必须是单一选择,编辑必须是在编辑过程中没有选择 你也可以改变uttableviewcell属性中的设置 在表格视图单元格中编辑 样式必须是自定义的,标识符必须是Rid section为none

请检查UITapGestureRecognizer。 在我的例子中,tapgesture被添加到tableview所在的视图中,这消耗了UITableview的用户交互,比如didselect。 在禁用视图的tapgesture后,触发了didselect delegate
tableView?.allowsSelection = true

在Xcode 11.7中默认为False

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

一个常见的错误是编写调用selectRowAtIndexPath或deselectRowAtIndexPath的代码,并假设该调用将触发对委托的didSelectRowAtIndexPath的调用。但事实并非如此。

selectRowAtIndexPath和deselectRowAtIndexPath的文档清楚地说明:

这些方法不会调用委托方法 tableView:willSelectRowAtIndexPath:或tableView:didSelectRowAtIndexPath:,也不会发送通知。"