Swift 4:didSelectRowAt代理方法未触发问题求助
我之前也踩过这个一模一样的坑!你已经排查了协议声明、Storyboard关联、Cell交互开关这些常规项,那咱们来看看几个容易被忽略的原因:
检查自定义Cell内的子控件是否拦截了点击
如果你的自定义Cell里有覆盖整个Cell区域的控件(比如一个填充整个Cell的UIView、UIButton),而且这些控件的isUserInteractionEnabled是true,那么点击事件会被这些子控件优先捕获,导致TableView的didSelectRowAt无法触发。
解决办法:对于不需要交互的子控件,手动设置isUserInteractionEnabled = false;如果是需要交互的控件,确保它们的点击事件不会覆盖整个Cell的点击范围。确认TableView的
allowsSelection属性未被禁用
有时候会在代码里不小心设置了tableView.allowsSelection = false,哪怕Storyboard里已经勾选了允许选择,代码里的设置会覆盖Storyboard的配置。你可以在viewDidLoad里加一行打印确认:print("TableView allows selection: \(tableView.allowsSelection)")如果输出是
false,把它改成true即可。检查TableView是否被其他视图遮挡
有可能存在一个透明的UIView或者其他控件叠在TableView上方,挡住了用户的点击操作。你可以通过Xcode的Debug View Hierarchy功能查看视图层级,确认TableView是处于最上层的可交互视图。核对代理方法的签名是否完全正确
虽然你贴的代码看起来没问题,但有时候会因为拼写错误或者参数不匹配导致方法无法被系统调用。再仔细核对一遍方法签名:func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print(indexPath.row) }确保没有把
didSelectRowAt写成OC时代的didSelectRowAtIndexPath,也没有写错参数名或类型。确认delegate未被意外重置
检查代码中有没有在viewDidLoad之后的某个地方,把tableView.delegate设为nil或者其他对象。可以在设置delegate的地方和didSelectRowAt方法里都加上断点,确认最终TableView的delegate确实指向当前ViewController。
我当时遇到这个问题,是因为在自定义Cell里加了一个填充整个Cell的背景View,忘记把它的isUserInteractionEnabled设为false,导致所有点击都被这个背景View拦截了,修改之后就正常触发didSelectRowAt了。
内容的提问来源于stack exchange,提问作者PruitIgoe

