why touchesBegan not called when UITableView subview is touched but is called for other subviews


I have:

  • UIView1 which overrides touchesBegan
  • I add a subView to UIView1 which contains UIView2, UITableView, UIView3
  • When I touch UIView2 or UIView3, UIView1.touchesBegan gets called
  • However, when I touch UITableView, UITableView.didSelectRowAtIndexPath() gets called but UIView1.touchesBegan does not get called.

Can you explain what is happening?

>Solution :

The reason why UIView1’s touchesBegan method is not getting called when you touch the UITableView is because the UITableView is intercepting the touch events and handling them itself. When a touch event occurs on a UITableView, the UITableView first checks if the touch event corresponds to a row selection, and if so, it calls the didSelectRowAtIndexPath method. If the touch event does not correspond to a row selection, the UITableView will pass the event on to its superview (in this case, UIView1) for further handling.

To have UIView1’s touchesBegan method called when the UITableView is touched, you can do the following:

  1. Set the userInteractionEnabled property of the UITableView to false. This will prevent the UITableView from intercepting touch events and instead pass them on to its superview.

  2. Implement the hitTest method in UIView1 to check for touch events on the UITableView and call the didSelectRowAtIndexPath method manually.

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    if let tableView = subView.tableView, !tableView.isHidden && tableView.frame.contains(point) {
    let indexPath = tableView.indexPathForRow(at: tableView.convert(point, from: self))
    if let indexPath = indexPath {
    tableView.delegate?.tableView?(tableView, didSelectRowAt: indexPath)
    return nil
    return super.hitTest(point, with: event)

Keep in mind that by disabling the user interaction, you will also need to handle the selection of the row in a different way.

You can also achieve this by creating a custom UITableViewCell subclass and override its touchesBegan method, and then call the UIView1’s touchesBegan from the UITableViewCell’s touchesBegan method.

Leave a Reply Cancel reply