Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pan-To-Pop conflicts with leadingSwipeActions on UITableView cells #6

Open
Enricoza opened this issue Jan 12, 2021 · 7 comments · May be fixed by #8
Open

Pan-To-Pop conflicts with leadingSwipeActions on UITableView cells #6

Enricoza opened this issue Jan 12, 2021 · 7 comments · May be fixed by #8
Labels
bug Something isn't working enhancement New feature or request

Comments

@Enricoza
Copy link
Owner

On a tableView with leadingSwipeActions the pan-to-pop gesture takes precedence over the _UISwipeActionPanGestureRecognizer of the tableView, making it impossible to show and activate those leading actions.

It should be allowed to, at least, disable the pan-to-pop entirely on some view controllers or, even better, it should be allowed to make it require the other gesture to fail and, therefore, take precedence.

@Enricoza Enricoza added bug Something isn't working enhancement New feature or request labels Jan 12, 2021
@ReDetection
Copy link
Contributor

I think it's worth to look into gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) and gestureRecognizer(_:shouldRequireFailureOf:) delegate methods. I was nearly able to achieve desired behavior, but seem to miss something since I didn't get it robust

@ReDetection
Copy link
Contributor

OK I'm stuck again. There are two system recognizers we would be probably interested in:

  • _UISwipeActionPanGestureRecognizer which is used for actions (including delete) and we definitely don't want to conflict with, so we'd like to require it's failure in order to begin your pan gesture recognizer. Fortunately it quickly understands if touch is eligible for the gesture and fails itself
  • UIScrollViewPanGestureRecognizer which is used for general scrolling of the scroll view. We'd like to require it's failure in order to begin pan to pop gesture, but unfortunately it doesn't fail itself if we scroll sideways, even though only vertical scroll should be considered.

You can see for the shitty workaround in my demo-delegate branch.

@ReDetection
Copy link
Contributor

The best debug trick I know is to set a symbolic breakpoint on -[UIWindow sendEvent:] and add an automatic debugger command po [[[$arg3 allTouches] anyObject] gestureRecognizers] and enable automatic continue. This way you can observe all the recognizers and their states as they change

ReDetection added a commit to ReDetection/EZCustomNavigation that referenced this issue Jan 13, 2021
@ReDetection ReDetection linked a pull request Jan 13, 2021 that will close this issue
@ReDetection
Copy link
Contributor

Ha, scroll view exposes it's pan gesture recognizer :) so the workaround just got a lot better. Please see the #8

@Enricoza
Copy link
Owner Author

Hi @ReDetection,
it's needlessly to say how much I appreciate your work and tips. It really helps a lot, so thanks.

I had found the _UISwipeActionPanGestureRecognizer too, but since it's private I wouldn't want to hardcode its name.

Anyway thanks also for the PR, it's highly appreciated. Unfortunately I can't review it right now but I will look at it later today.

@VasApps
Copy link

VasApps commented Mar 12, 2021

I had this issue in my app as well and I managed to fix it by recursively searching for the tableView in the last viewController of the navigation stack. Once you find the tableView you can simply check for isEditing and then return. I attached the code below.

` private func handleGestureRecognizer(_ gestureRecognizer: UIPanGestureRecognizer, forPop: Bool) {

    let viewControllers = visibleViewController?.navigationController?.viewControllers

    var isEditingTableView = false
    
    if viewControllers != nil {
        
        let lastVC = viewControllers![viewControllers!.count - 1]
        
        if let tableView = lastVC.view.recursiveSearch(type: UITableView.self) as? UITableView{
            
            isEditingTableView = tableView.isEditing
            
        }
    }
    
    if isEditingTableView {
        
        return
    }
    

    guard let gestureRecognizerView = gestureRecognizer.view,
        enableFollowingGesturesWhileAnimating || !coordinator.onGoingAnimation else {
        return
    }
    
    let percent = gestureRecognizer.translation(in: gestureRecognizerView).x / gestureRecognizerView.bounds.size.width
    onInteractiveGestureRecongnizerState(gestureRecognizer.state,
                                         percent: forPop ? percent : -percent,
                                         onShouldActivate: forPop ? self.onShouldPopViewController : self.onShouldUnpopViewController)
    
}`

@Enricoza
Copy link
Owner Author

Hi @VasApps! First and foremost, thank you for your input.

Unfortunately I think your issue is not the same we are talking about in this thread and your solution is, anyway, not really viable.

Here we are talking about a tableView that has the method leadingSwipeActionsConfigurationForRowAt implemented and returning some UIContextualAction for some row. In this case the left-to-right swipe conflicts with that swipe action that opens the left menu, so the leadingActions can never be triggered.
This API is not triggered just when the tableView is in Editing mode, so your code would serve no purpose in this case.

That said, assuming there is another issue when a tableView is in editing mode, your solution would prevent whatever pop gesture (if there is any tableView in editing mode) while still capturing the gesture priority and therefore preventing whatever other left-to-right pan gesture that goes in conflict. This is not the intended behavior.

Even if it were, I don't think that looking for the tableView recursively would be something that can be part of this library.

If you feel like I miss interpreted something you just said, you can correct me and let me understand better.
You can also open a new issue if this actually is an entirely new issue and doesn't regard leadingSwipeActionsConfigurationForRowAt and explain more precisely what is that you would like to happen versus what actually is happening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants