简体   繁体   中英

UIPanGestureRecognizer does not forward touches

I have couple of UICollectionView in my UIViewController . On top of the VCs view I have a UIGestureRecognizer .

I would like the UIGestureRecognizer to fire up, make his logic and forward the touch to the underling views to their thing (like scrolling the collection views).

I've set the property cancelsTouchesInView of the UIGestureRecognizer to NO . But it didn't help.

These didn't help neither:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if ([gestureRecognizer isMemberOfClass:[UIPanGestureRecognizer class]]) {
        return YES;
    }
    return NO;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if ([gestureRecognizer isMemberOfClass:[UIPanGestureRecognizer class]]) {
        return YES;
    }
    return NO;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([gestureRecognizer isMemberOfClass:[UIPanGestureRecognizer class]]) {
        return YES;
    }
    return NO;
}

First of all, UIGestureRecognizer is an abstract base class. You have to specify one of its subclasses for usage: UITapGestureRecognizer , for example. Next, you have to set its delegate and return YES from shouldRecognizeSimultaneouslyWithGestureRecognizer delegate method. I think that it should work then.

But let me ask you something: Why don't you use your collection views delegate method didSelectItem:atIndexPath in the first place?

I was stuck on a problem like yours about two years ago, but my problem was with a MKMapView and not a UICollectionView, but I believe the we can resolve it.

Did you check that maybe you are not receiving delegate messages because the UICollectionView is consuming the touch and your gesture is never reached?

  • Try attaching your gesture on the UICollectionVIew instead on your VCs's view.

It should work, but if not, try removing your UICollection just for test, attach the gesture on your VC's view and tap the view to have sure the gesture is working.

  • If even without your UICollectionView on the view's hierarchy the UIGesture not works, you are not initialising it correctly.

Ok, if your delegate is been called when your gesture is attached on the VC's view but not when you attach it on the UICollectionView, I'm pretty sure you are having some gesture conflicts between your gesture and the UICollectionView's ones.

  • In this case, loop your UICollectionView's gestures and require a fail response from your gesture. Take this snippet:

     for (UIGestureRecognizer *gesture in collectionView.gestureRecognizers) { [gesture requireGestureRecognizerToFail:yourGesture]; } 

Or ...

Subclass a UIView, put it on the most top of your view controller, above your UICollectionView, and override

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

method, do your stuff inside it, and return nil to pass the touch to the view above...

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

    //Do your stuff here ... you can also
    //return self; if you want to consume the touch

    //You can make this UIView's subclasse a "TouchDetector layer"
    //and call a delegate from here to notify other classes that 
    //this view is been touched...

    //returning nil, the touch will not be blocked and will be reached
    //by the view above it.
    return nil; 
}

I hope one of the above resolves your problem. Or at least takes you to the right way...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM