applidium / OverlayContainer

Non-intrusive iOS UI library to implement overlay based interfaces
https://gaetanzanella.github.io/2018-12-17/replicating-apple-maps-overlay
Other
1.15k stars 94 forks source link

Gesture recognizer conflicts with UITableViewCell gesture recognizers for cell actions #71

Closed bryan1anderson closed 4 years ago

bryan1anderson commented 4 years ago

Describe the bug Gesture recognizer conflicts with UITableViewCell gesture recognizers for cell actions Expected behavior I should reliably be able to swipe on a cell when it is placed in the overlaycontainer.

I pan gesture property is private so I don't have access to require it to fail to the cell swipe gestures.

How do I get swipeable tableviewcells to work using OverlayContainer?

hberenger commented 4 years ago

I had exactly the same issue as yours: it was not possible to open the the Swipe Actions of a tableview embedded in an OverlayContainer, below the overlay view controller.

It seems that, as you mention, there is a conflict between the tableview gesture recognizers and the OverlayTranslationGestureRecognizer defined by the OverlayContainer library (subclass of UIPanGestureRecognizer). It happens that :

So, I came up with the following workaround, consisting in implementing gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) for the internal pan recognizer :

// Defined on client application side:
class OverlayContainerTweak: NSObject, UIGestureRecognizerDelegate {

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                           shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

then:

let overlayTranslationGestureRecognizer = overlayContainerViewController.view.gestureRecognizers?.first {
    String(describing: type(of: $0)).contains("OverlayTranslationGestureRecognizer")
}

(where overlayContainerViewController is the OverlayContainerViewController), and finally:

let overlayContainerTweak = OverlayContainerTweak()
overlayTranslationGestureRecognizer?.delegate = overlayContainerTweak

Clearly this is pretty hacky, but it did the job. Not sure whether returning always true is meaningful from the library point of view, so I did not submit any PR to push this fix on the library side.

@gaetanzanella : if you confirm that the OverlayTranslationGestureRecognizer should always be recognized simultaneously with other gesture recognizers, I can submit a fix similar to the workaround above. Let us know what you think.

bryan1anderson commented 4 years ago

@hberenger So this allowed you to use the tableview actions?

@gaetanzanella I'm always afraid of claiming delegate ownership to gestures as that can cause problems if it relies on it somehow. Do you have any recommendations?

hberenger commented 4 years ago

@bryan1anderson : yes, I confirm this workaround repaired the tableview swipe actions

gaetanzanella commented 4 years ago

Hi @bryan1anderson @hberenger, thanks for raising the issue. A fix is available. I will release it soon.

If you return false in the shouldStartDraggingOverlay callback, the container pan gesture will be disabled. So you can do something like:

func overlayContainerViewController(_ containerViewController: OverlayContainerViewController,
                                    shouldStartDraggingOverlay overlayViewController: UIViewController,
                                    at point: CGPoint,
                                    in coordinateSpace: UICoordinateSpace) -> Bool {
    let position = overlayViewController.view.convert(point, from: coordinateSpace)
    return overlayViewController.view.bounds.contains(position)
}
bryan1anderson commented 4 years ago

But I don't want it to be disabled. There is effectually a point on every single point on the view because its just a tableview. I need them to behave together. I don't care about horizontal pans on the container view, and I don't care about vertical pans on the tableview. It seems what you're saying the fix does is just not allow panning if the touch is on a certain point. All my points need to be able to handle both of these @gaetanzanella

gaetanzanella commented 4 years ago

I'm not sure I understand. Could you provide a sample code?

bryan1anderson commented 3 years ago

@gaetanzanella Sorry to be unclear. Your solution doesn't support recognizing multiple gesture recognizers. Your solution seems to support only supporting panGesture1 or panGesture2. I need it to recognize both of them simultaneously

For example: If my entire view needs to be swiped on from left to right. There is no point at which I don't want the view to be swiped on. Therefore I either need to disable OverlayContainer pan gesture, or I need to disable my views pan gesture. I need simultaneous gestures