Search code examples
iosswiftuigesturerecognizeruipangesturerecognizer

UIPanGestureRecognizer on tableView does not scroll table items


Using UIPanGesture on a UITableView (Swift 4.0) to drag the tableview position (i.e. origin). UIPanGestureRecognizer detecting touch events and consuming them. At some point I want to delegate the events to table so it will scroll its items. How can I do so?

What have I tried:

@objc func tableViewDragged(gestureRecognizer: UIPanGestureRecognizer) {

        if gestureRecognizer.state == UIGestureRecognizerState.began || gestureRecognizer.state == UIGestureRecognizerState.changed {

            let translation = gestureRecognizer.translation(in: self.view)

// if origin moved to map origin it should not scroll above but cell should scroll normally. But returning does not help scrolling cells
            if self.tableView.frame.origin == self.mapContainer.frame.origin && translation.y < 0 {

                return
            }

            var frame = self.tableView.frame
            let nHeight = (frame.origin.y + translation.y)

            if (nHeight < self.view.frame.size.height) {

                frame.origin.y = nHeight
                self.tableView.frame = frame
                gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
            }
        }
}

Gesture added to tableView

let gesture = UIPanGestureRecognizer(target: self, action: #selector(self.tableViewDragged(gestureRecognizer:)))
self.tableView.addGestureRecognizer(gesture)
self.tableView.isUserInteractionEnabled = true
gesture.delegate = self

Problem Summary:

For the same pan gesture at any point of tableview (i.e. on any cell), I need to scroll items when tableviews origin got fixed in top left corner of the container. Otherwise I have to move the tableview until its got attached to top left point. Moreover If If nothing to scroll down I need to again move the table below for pan down gesture.

*Problem Usecases: *

  1. initial condition - tableview origin is at middle of the screen, i.e. (0, Height/2)
  2. pan up gesture - table moved up vertically, but no item scrolls, until origin got stuck to (0,0)
  3. pan up gesture - cell items moved up but not table itself
  4. pan up gesture - cell items moved up until end of the cells
  5. pan down gesture - cell items moved down until index 0, lets say came to 0 index
  6. pan down gesture - tableview moved to down vertically until its origin reached to middle of the screen (0, Height/2)

Solution

  • If I am understanding it correctly so you want to cancel PanGesture when you want to Scroll.

    Try this :

    func isItemAvailabe(gesture: UISwipeGestureRecognizer) -> Bool {
        if gesture.direction == .down {
            // check if we have some values in down if yes return true else false
        } else if gesture.direction == .up {
            // check if we have some values in up if yes return true else false
        }
        return false
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                           shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        if gestureRecognizer == self.panGesture && otherGestureRecognizer == self.scrollGesture && isItemAvailabe(gesture: otherGestureRecognizer) {
            return true
        }
        return false
    }
    

    Let me know if this solve your problem or I am not getting it correctly.

    Also remember to add this too :

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {
        return YES;
    }
    

    You can check more here