1
votes

I am installing a UIPanGestureRecognizer on the main view as follows:

  panGesture = UIPanGestureRecognizer(target: self, action: #selector(previewPanned(_:))
  panGesture?.minimumNumberOfTouches = 1
  panGesture?.maximumNumberOfTouches = 1               
  view.addGestureRecognizer(panGesture!)

The problem is it gets simultaneously recognised with the system swipe gesture on home indicator to dismiss the app. How do I avoid this conflict?

EDIT: The problem arises when I dimmed home button indicator using the following code -

   override var prefersHomeIndicatorAutoHidden: Bool {
      return false
   }

   override var preferredScreenEdgesDeferringSystemGestures: UIRectEdge {
       return [.bottom, .top]
   }

The above code dims the home indicator after few seconds. Then you need to swipe twice to dismiss the app -- the first one to undim the home indicator and the second one to dismiss the app. The first swipe does both, invokes my pan gesture recognizer as well as undims the home indicator. I don't want my pan gesture recognizer to be called during the first swipe.

1
The problem is once you get out of the safe area there is not much to be done, that's why it is delimited in that way so that you don't encounter any unexpected behaviour. Nevertheless what you could do is check when the home button is being swiped with applicationWillResignActive() and undo your pan action in that moment before leaving.ERP
The home button has already been dimmed by me. If it is not dimmed, it always takes precedence and there is no issue. But once it is dimmed, it takes an edge swipe to first undim it. Then another edge swipe to dismiss the app. It is the first edge swipe to undim the home button that causes the conflict.Deepak Sharma

1 Answers

3
votes

If I understood you correctly, you don't want your recognizer to work near home indicator, so you have two options:

  1. Create a view specifically for this recognized and layout its bottom to the safe layout guide.
  2. Implement a gesture recognizer delegate method shouldReceive touch: and check if the touch is in the save bounds:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        let safeAreaFrame = view.bounds.inset(by: view.safeAreaInsets)
        return safeAreaFrame.contains(touch.location(in: view))
    }
    

Second case is implemented in the following sample project