Get Swipe to Delete on UITableView to Work With UIPanGestureRecognizer
Asked Answered
B

3

8

I have a UIPanGuestureRecognizer added to the entire view using this code:

UIPanGestureRecognizer *pgr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
[[self view] addGestureRecognizer:pgr];

Within the main view I have a UITableView which has this code to enable the swipe to delete feature:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"RUNNING2");
    return UITableViewCellEditingStyleDelete;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row >= _firstEditableCell && _firstEditableCell != -1)
        NSLog(@"RUNNING1");
        return YES;
    else
        return NO;
}

Only RUNNING1 is printed to the log and the Delete button does not show up. I believe the reason for this is the UIPanGestureRecognizer, but I am not sure. If this is correct how should I go about fixing this. If this is not correct please provide the cause and fix. Thanks.

Baileybailie answered 22/8, 2013 at 0:31 Comment(4)
Have you set your class to be the table view's delegate?Endearment
@Endearment Yes. Also I do not think that RUNNING1 would be printed if I didn't. But thanks for trying.Baileybailie
canEditRorAtIndexPath: is a data source method, not a delegate method, so it would run if you hadn't set the delegate.Endearment
@Endearment Thanks for the clarification, but yes I have.Baileybailie
M
16

From the document:

If a gesture recognizer recognizes its gesture, the remaining touches for the view are cancelled.

Your UIPanGestureRecognizer recognizes the swipe gesture first, so your UITableView does not receive touches anymore.

To make the table view receives touch simultaneously with the gesture recognizer, add this to the gesture recognizer's delegate:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}
Moskow answered 22/8, 2013 at 8:51 Comment(1)
Exactly what I was looking for. Works beautifully. Thanks!Baileybailie
M
2

If you are using UIPanGuestureRecognizer for example to show side menu you might see some unwanted side effects when you just return YES in all cases as proposed in accepted answer. For example the side menu opening when you scroll up/down the table view (with additional very little left/right direction) or delete button behaving strangely when you open the side menu. What you might want to do to prevent this side effects is to allow only simultaneous horizontal gestures. This will make the delete button work properly but at the same time other unwanted gestures will be blocked when you slide the menu.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
    {
        UIPanGestureRecognizer *panGesture = (UIPanGestureRecognizer *)otherGestureRecognizer;
        CGPoint velocity = [panGesture velocityInView:panGesture.view];
        if (ABS(velocity.x) > ABS(velocity.y))
            return YES;
    }
    return NO;
}

or in Swift:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    guard let panRecognizer = otherGestureRecognizer as? UIPanGestureRecognizer else {
        return false
    }
    let velocity = panRecognizer.velocity(in: panRecognizer.view)
    if (abs(velocity.x) > abs(velocity.y)) {
        return true
    }
    return false
}
Manciple answered 29/7, 2017 at 7:40 Comment(0)
A
0

If the accepted answer does not work. Try adding

panGestureRecognizer.cancelsTouchesInView = false

Ensure you haven't added the gesture to the tableview directly. I added a pan gesture on the ViewController view and can confirm it works.

Automate answered 1/5, 2019 at 2:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.