嵌套在UIViewController中的UITableViewController的didSelectRowAt不触发
解决UITableViewController嵌套后didSelectRowAt不触发的问题
我之前也碰到过完全一样的情况!结合你的代码来看,最可能的问题出在子控制器添加的步骤顺序上,另外还有几个常见的排查点可以一起检查:
1. 修正子控制器的添加顺序(最可能的解决方案)
你当前的代码里,在把tableView添加到父视图之前就调用了didMove(toParent:),这违反了UIKit子控制器的生命周期流程,会导致视图和控制器的关联出现异常,进而影响事件传递。
正确的添加流程应该是:
- 创建子控制器实例
- 调用
addChild(_:)建立父子关系 - 将子控制器的view添加到父视图层级
- 设置view的约束
- 最后调用
didMove(toParent:)通知子控制器完成移动
修改后的setupTableView代码如下:
private func setupTableView() { let tableVC = NewHouseTableController() self.addChild(tableVC) let tableView = tableVC.view! self.view.addSubview(tableView) tableView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: self.totalTf.bottomAnchor, constant: 16), tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor) ]) // 把这一步移到添加view并设置约束之后 tableVC.didMove(toParent: self) }
2. 其他排查点
如果调整顺序后还是没解决,可以检查以下几点:
- 检查是否有视图遮挡tableView:父控制器的view上有没有其他透明/半透明的UIView、手势识别器覆盖在tableView上方?可以通过Xcode的Debug View Hierarchy工具查看视图层级,确认tableView在最上层。
- 确认tableView的交互开关:虽然默认是开启的,但可以在子控制器的
viewDidLoad里显式添加self.tableView.isUserInteractionEnabled = true,排除意外被关闭的可能。 - 检查父控制器的手势拦截:如果父控制器添加了全局的UITapGestureRecognizer,可能会拦截tableView的点击事件。可以给手势设置delegate,实现
gestureRecognizer(_:shouldReceive:)方法,让手势忽略tableView区域的点击:func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { return touch.view?.isDescendant(of: tableView) == false } - 排除子控制器被提前释放:虽然
addChild会让父控制器持有子控制器,但如果你的业务逻辑里有特殊处理,可以给父控制器添加一个强引用的属性(比如var tableVC: NewHouseTableController?)来持有子控制器实例,避免被提前释放。
内容的提问来源于stack exchange,提问作者stephen
相关产品推荐
相关产品推荐

