質問

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.

役に立ちましたか?

解決

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;
}

他のヒント

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
}

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.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top