-didSelectRowAtIndexPath:不被调用


295

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

有谁知道我可能为实现这一目标而搞砸了什么?


79
您也可能在UITableView顶部有一个手势识别器来吸收选择..(一种可能)
M.Othman 2012年

如果要填充表视图,请小心,这意味着数据源设置正确。选择是Delegate方法的一部分。因此,也许DataSource设置良好,但Delegate却没有!
Thomas Besnehard

1
嗨,Othman,您的评论恰恰是我自己的问题所在。您知道如何让手势识别器与一起工作UITableView吗?
3

15
我注意到,如果我点击并按住,则该点击最终会调用-didSelectRowAtIndexPath。我发现这是因为在桌面视图上有一个轻击手势识别器,并且手势必须先失败才能接收到触摸。尽管很奇怪,但表选择动画不受手势识别器的影响。
Hlung 2013年

6
我在这里遇到了同样的问题,并且有幸了解到您不能在UITableView的顶部有一个handleRecognizer。谢谢奥斯曼先生!
vnchopra 2014年

Answers:


97

听起来好像该类不是该UITableViewDelegate表视图的,尽管UITableViewController应该自动设置该类。

您是否有可能将代表重置为其他班级?


7
我发现,虽然我的控制器是UITableViewController,但我在UI Builder中使用了一个普通的旧UIViewController小部件。那不行 当我删除UIViewController小部件并将UITableViewController放在其位置时,一切正常。
Matt Pfefferle,

1
每个人的另一个极端情况-我用代码将代表连接起来,却忘记了我以前是通过情节提要线连接代表的。
奥利弗·邓吉

1
请问如何显示“将代表重置为其他班级”?我遇到了同样的问题,无法解决
Alfro

1
myTableViewController.tableView.delegate = xxx
Hunter

534

万一有人犯了和我一样的愚蠢错误:

检查是否didSelect可能didDeselect以某种方式意外获得了您所期望的方法名称。我花了大约两个小时才找到...


47
这里同样的问题。这是因为XCode在选择之前自动完成取消选择。
user1021430 2013年

同样,我设置了allowSelection = false,除了删除所有选择突出显示之外,还防止了单元格被按下!
djinne95

503

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

UITableView选择种类

应该是Single Selection正常的选择,应该不会No Selection

要以编程方式执行此操作,请执行以下操作:

tableView.allowsSelection = YES

4
我一直碰到这个问题是因为我的场景始终处于编辑模式,而我一直忘记将默认设置从“编辑期间无选择”更改为默认设置。
2012年

3
您可以在viewControlller NSParameterAssert(self.tableView.allowsSelection);的-viewDidLoad方法中添加此行。
Nikolay Shubenkov 2015年

对于那些观察tableView.rx.itemSelected.subscribe并没有回叫的人,这是问题所在,并且上面的修复方法都有效
Dhilip

如此的帮助,当你接手一些代码库,它有使用带有标记的按钮代码,而不是didSelectRow,这种选择在故事板🙄禁用
尼廷Alabur

这个tableView是默认行为吗?
Frostmourne

296

另一个可能性是UITapGestureRecognizer可能正在吞噬事件,如此处所示:https ://stackoverflow.com/a/9248827/214070

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


这是我的问题!非常感谢!!我的意思是说它以前显然已经工作了,但是在我实现了UITapGestureRecognizer之后,它停止了工作。[self.view addGestureRecognizer:tap];
coolcool1994

26
我遇到了与您刚刚实施的@ coolcool1994相同的问题[点击setCancelsTouchesInView:NO]; 解决了这个问题
nizx 2014年

谢谢,对我有帮助。就我而言didSelectRowAtIndexPath,仅在删除in中的单元格后才起作用commitEditingStyle。然后,我让UITapGestureRecognizertapAction:得到了indexPath来自sender.view[self.tableView indexPathForCell:sender.view])和呼叫[self.tableView.delegate didSelectRowAtIndexPath:myIndexPath]
Alexmelyon

1
这也是我的问题。.添加代码以删除tableview中的tapgesture,它的工作方式就像是魅力-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {UITapGestureRecognizer * gesture = [[UITapGestureRecognizer alloc ] 在里面]; pose.cancelsTouchesInView = NO; [self.tableView addGestureRecognizer:gesture]; }
Udaya Sri

6
感谢@nizx,迅速4 tap.cancelsTouchesInView = false
Ariven Nadar 18-4-24

150

所有好的答案,但还有更多需要注意的地方...

(尤其是在以编程方式创建UITableView时)

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


9
我将添加setAllowsSelectionDuringEditing:到列表中(当tableview处于编辑模式时)
alex-i

谢谢!在IB中,我必须将“选择”部分的值更改为Single Selection
萨sho

90

如果出现问题,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

67

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

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

  2. 您的行中可能有一个UIView,它是第一响应者,可以带走您的点击。说一个UIButton或类似的东西。


5
它开始在iOS 7上发生,在contentView中禁用了视图的“ User Interaction Enabled”,从而解决了此问题。
2013年

1
@Kof钉牢了。在Xcode 5的界面构建器中创建UITableViewCell会在启用用户交互= YES的情况下创建它。错误的Xcode 5!
jsd

44

我曾经也有过一样的问题。而且很难找到。但是在我的代码中是这样的:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    return nil;
}

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


2
为SelectRow在IndexPath做的正确签名是:-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
coolcool1994

对我来说,直到我完全删除了willSelectRowAtIndexPath之后,它才开始调用tableView:didSelectRowAtIndexPath
etayluz 2015年

38

如果您在UITableView的顶部添加了gestureRecognizer,didSelectRowAtIndexPath将不会被调用。

因此,您需要使用gestureRecognizer委托方法来避免在特定视图中触摸。

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

3
if ([touch.view isDescendantOfView:YourTable])
Sudheesh

29

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

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

它应该为一行返回YES以便将其选中。


24

您必须选择这些选项

在此处输入图片说明

但是如果您不想UITableView在单击时突出显示,则应该更改UITableViewCell属性。

选择无选择选项,如下所示

在此处输入图片说明


20

UITapGestureRecognizer在表格视图上放了一个,以关闭阻止didSelectRowAtIndexPath:被调用的键盘。希望它能帮助某人。



19

我有同样的问题,

原因是使用UITapGestureRecognizer。我想在其他任何地方轻按时关闭键盘。我意识到这会覆盖所有轻按动作,这就是为什么didSelectRowAtIndexPath未调用函数的原因。

当我注释与相关的行时UITapGestureRecognizer,它起作用。此外,您可以检查UITapGestureRecognizer selector是否点击了功能UITableViewCell



11

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


10

即使接受了另一个答案,我也会为观察此问题的人添加一个可能的问题和解决方案:

如果打开了自动引用计数(ARC),则可能会发现,即使将控制器分配为视图的委托之后,由于ARC正在删除控制器,因此也不会收到视图发送给控制器的消息。显然,UITableView的委托指针不会算作ARC的引用,因此,如果这是对其的唯一引用,则控制器将被取消分配。您可以通过在控制器上实现dealloc方法并在其中设置断点或NSLog调用来验证是否正在发生这种情况。

解决方案是跟踪控制器,并在其他地方提供强大的参考,直到您确定不再需要它为止。


仍然显示其视图时正在对控制器进行垃圾回收?这真的可以发生吗?
Drux

@Drux Yep!当我遇到这种情况时,这几乎是iOS上使用的具有垃圾回收功能的Obj-C的第一个版本,老实说,他们做得并不出色。国际海事组织(IMO)本应强烈地暗示或暗指许多“弱点”。这导致了诸如显示层正在积极使用的对象的垃圾回收之类的怪异现象。我有一段时间没有做过iOS工作了,所以我不知道在最新版本上是否仍然会发生这种情况。
Andrew Gorcester 2014年

我的代码有不断增长的内存大小问题,仅在didSelect不会被首次调用之后,我才对其进行了一些修复。我不知道这是否可以解决问题。
琥珀K

10

请记住,如下设置viewDidLoad方法中的数据源和委托:

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];

我正在打电话给数据源,但没有打电话给我……谢谢!
Gmeister4,2016年

9

我的问题不是以上所有。如此la脚。但是我想我会在这里列出它,以防它对某人有所帮助。

我有一个tableViewController是我的“基本”控制器,然后创建了该控制器的子类。我tableView:didSelectRowAtIndexPath在“基础”类的例程中编写了所有代码。完全忘记了默认情况下,我的所有子类中也都创建了该例程(尽管没有代码执行任何操作)。因此,当我运行我的应用程序时,它运行了代码的子类版本,什么也没做,使我感到难过。因此,当然,一旦我从子类中删除了例程,它就使用了mt“ base”类例程,并且我开始从事商业活动。

我知道。不要笑 但这也许可以节省我失去的时间……


8

为此,给我2美分。

我有一个Custom UITableViewCell,并且有一个覆盖整个单元格的按钮,因此当发生触摸时,选择的是按钮而不是单元格。

要么删除按钮,要么就我而言,我将按钮上的User Interation Enable设置为false,这样该单元格即被选中。


8

如果您阅读此内容,那么仍然无法解决问题。

我有自定义单元格,其中复选框“ User Interaction Enabled ”已禁用。所以,我只是打开它。祝好运。


7

我刚刚遇到了这个事情,就像过去发生的那样,它没用,因为我在尝试添加方法时没有注意自动完成,最终我实现了tableView:didDeselectRowAtIndexPath:代替tableView:didSelectRowAtIndexPath:


7

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

这是不止几次让我着迷的!!


5

我知道它已经很旧并且问题已经解决,但是有一个类似的问题,我认为问题出在我的自定义UITableViewCell上,但是解决方案完全不同-我重新启动XCode :),然后可以正常工作!几乎像Windows :)


5

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


4

您可能会犯的另一个错误(就像我一样):如果在单元格上设置了segue,didSelectRowAtIndexPath则不会调用。您应该改为在视图控制器上设置segues。


4

这些答案都不对我有用。大约一个小时后,我发现了一个非常阴险的东西:

我在另一个表视图的单元格内有一个表视图。我决定制作一个包含内部表视图的封闭视图。我将此视图称为contentView并将其连接到xib中。

事实证明,UITableViewCell已经具有一个contentView并对其进行处理。当我将属性重命名为mainContentView并将视图重新连接到此重命名的属性时,问题自行解决。


4

就我而言,我动态计算的高度TableViewSuperView在加载时间。由于计算错误,放置在的TableView外部SuperView。在TableView绘制精细,但是所有的互动是无效(且didSelectRowAtIndexPath从未被调用)。很难检测到,因为没有视觉上的指示,表明“ TableView不可访问”。


4

就我而言,问题是我有一个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
}

1
可以确认这尤其对我造成了OP的问题
Josh Wolff

4

在我的情况下,解决方案是在以下函数中将“否”更改为“是”。

iOS 9+

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

这也是我的问题。我有多个tableView实现,并且忘记了用此方法将两个tableView分开。
turingtest
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.