Why does tableview slide in one UIPanGestureRecognizer implementation but not the other?

42 Views Asked by At

UITableView And UIPanGestureRecognizer

I added UIPangesture in two different ways, but I don't understand why it produces different results I have checked a lot of documents and information, but I can not figure out the reason. We can see in the delegate method that both gestures are printed, so what is the reason for the failure of one of the gestures?

    private lazy var tableVeiw: UITableView = {
        let tableView = UITableView()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableHeaderView = UIView()
        tableView.tableFooterView = UIView()
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        return tableView
    }()
  private lazy var pan:UIPanGestureRecognizer = {
        let pan = UIPanGestureRecognizer(target: self, action: #selector(panAction(sender:)))
        return pan
    }()
override func viewDidLoad() {
        super.viewDidLoad()
        
        tableVeiw.frame = self.view.bounds
        pan.delegate = self
        //Case 1, sliding screen panAction method will print log, tableview does not slide
        self.view.addSubview(tableVeiw)
        tableVeiw.addGestureRecognizer(pan)
        // Case 2, slide the screen without executing panAction method, but tableview slide
        self.view.addSubview(tableVeiw)
        self.view.addGestureRecognizer(pan)
        
    }

    @objc func panAction(sender:UIPanGestureRecognizer) {
        print(#function)
    }
        func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        print(gestureRecognizer)
        return true
    }
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        print("ges----\(gestureRecognizer) other=======\(otherGestureRecognizer)")
        return false
    }

2

There are 2 best solutions below

1
Sudeep P H On

You're seeing different results in the two cases is due to the way gesture recognizers are handled by the system

  1. In Case 1, you added the pan gesture recognizer to the tableVeiw using tableVeiw.addGestureRecognizer(pan). This means that the gesture recognizer is associated with the tableVeiw itself. As a result, when you perform a pan gesture on the table view, the gesture recognizer recognizes it and triggers the panAction method

  2. In Case 2, you added the pan gesture recognizer to the view controller's view using self.view.addGestureRecognizer(pan). This means that the gesture recognizer is associated with the view controller's view. When you perform a pan gesture on the view, the gesture recognizer recognizes it. However, because you have not set any specific target or action for this gesture recognizer, it doesn't trigger the panAction method. Instead, it allows the gesture to propagate to other gesture recognizers that may be present, such as the one associated with the table view. As a result, the table view can still scroll because its own gesture recognizer is not blocked.

To summarize, in Case 1, the pan gesture recognizer is directly associated with the tableView, so it triggers the panAction method. In Case 2, the pan gesture recognizer is associated with the view controller's view, and since no specific action is defined for it, it allows other gesture recognizers to handle the gesture. The table view's gesture recognizer takes precedence and allows the table view to scroll.

0
Geoff Hackworth On

Adding the pan gesture recogniser to the view (case 2) does nothing because the table view completely obscures that view. You set the table view frame to the view’s bounds.