Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting swipe gestures on UITableViewCell inside UIScrollView

I am hoping someone will be able to help me with a problem that is doing my head in at the moment!

Given the following view hierarchy

enter image description here

I want to be able to detect swipe gestures on my custom UITableViewCell.

I have subclassed the UIScrollView and have a hitTest:withEvent: method that checks whether I am touching the tableview cell (or its content) or not, in which case I set the following scroll view properties:

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView* result = [super hitTest:point withEvent:event];
    if ([result.superview isKindOfClass:[UITableViewCell class]] || [result.superview tag] == SUBVIEW_TAG)
    {
        self.canCancelContentTouches = NO;  
        self.delaysContentTouches = YES;
    } else {
        self.canCancelContentTouches = YES;
        self.delaysContentTouches = NO;
    }
    return result;
}

I have also implemented:

- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
    if (view.tag == SUBVIEW_TAG || [[view superview] isKindOfClass:[UITableViewCell class]])
        return NO;
    return YES;
}

And am returning NO in case the view being touched is the table view cell.

These methods are all getting called and performing their actions as expected, but I am still unable to stop the UIScrollView from "hogging" the swipe gesture.

The interesting thing is that if I include the UIView that contains the tableview and cell on both of the methods above (the one with SUBVIEW_TAG) it works perfectly so I am guessing it must be something to do with the fact that UITableView inherits from UIScrollView.

My main goal is to be able to swipe on the cell to reveal more options for the cell. A horizontal swipe anywhere else on that view would be captured by the scroll view and shift the content horizontally as per its normal behaviour.

Any ideas would be very much appreciated!

Thanks! Rog

like image 242
Rog Avatar asked Sep 28 '11 09:09

Rog


1 Answers

I had a similar problem with a swipe detect for a component inside a scrollview and I was able to resolve it with

[scrollView.panGestureRecognizer requireGestureRecognizerToFail:swipeGesture]

Where scrollView is the scroll view object that acts like container and swipeGesture is the component swipe gesture object inside scrollview.

So, you can define a swipe for the cell object like this (for right swipe in the example, custom it as you want)

UISwipeGestureRecognizer* rightSwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(yourMethod)];
        [rightSwipeRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];

[cell addGestureRecognizer:rightSwipeRecognizer];

and then do

[scrollView.panGestureRecognizer requireGestureRecognizerToFail:rightSwipeRecognizer]

The documentation of requireGestureRecognizerToFail says:

This method creates a relationship with another gesture recognizer that delays the receiver’s transition out of UIGestureRecognizerStatePossible. The state that the receiver transitions to depends on what happens with otherGestureRecognizer:

If otherGestureRecognizer transitions to UIGestureRecognizerStateFailed, the receiver transitions to its normal next state.

if otherGestureRecognizer transitions to UIGestureRecognizerStateRecognized or UIGestureRecognizerStateBegan, the receiver transitions to UIGestureRecognizerStateFailed.

An example where this method might be called is when you want a single-tap gesture require that a double-tap gesture fail.

Availability Available in iOS 3.2 and later.

Hope helps!

like image 53
Francisco Hernandez Avatar answered Sep 28 '22 05:09

Francisco Hernandez