Horizontal scrolling UIScrollView with vertical pan gesture

十年热恋 提交于 2019-12-03 13:12:56

I think this will be difficult if you want to use a pan gesture because of the scroll view's use of those gestures. However, if you could use a swipe, it is easy to implement.

    UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
    swipe.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp;
    [self.scrollView addGestureRecognizer:swipe];

I tested this, and it worked fine to call the handler, and you don't need to disable the scroll view's pan gesture recognizer (in my test, the scroll view was tall enough and the content short enough that there was no vertical scrolling -- I don't know if this is necessary or not).

As of iOS 5, UIScrollView exposes its UIPanGestureRecognizer. Set your custom swipe’s delegate to self and make the gestureRecognizer a property or ivar, and make your class conform to the <UIGestureRecognizerDelegate> protocol. Then, implement UIGestureRecognizerDelegate’s – gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: like so:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if ([gestureRecognizer isEqual:self.swipe] && [otherGestureRecognizer isEqual:self.scrollView.panGestureRecognizer])
    {
         return NO;
    }
    return YES; // the default for this method
}
richy

I added a UIPanGestureRecognizer then setupgestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: like this:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([gestureRecognizer isEqual:self.panGesture] && [otherGestureRecognizer isEqual:self.collectionView.panGestureRecognizer]){
        return YES;
    }
    return NO;
}

I also added a check in gestureRecognizerShouldBegin:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ([gestureRecognizer isEqual:self.panGesture]) {
        if (gestureRecognizer.numberOfTouches > 0) {
            CGPoint point = [gestureRecognizer locationOfTouch:0 inView:gestureRecognizer.view];
            CGFloat distX = abs(self.collectionView.lastTouchPos.x - point.x);
            CGFloat distY = abs(self.collectionView.lastTouchPos.y - point.y);
            if (distX > distY) {
                return NO;
            }
        } else {
            return NO;
        }
    }
    return YES;
}

to only use self.panGesture when panning up or down.

Update

https://stackoverflow.com/a/8603839/667834 appears to have a better method for gestureRecognizerShouldBegin

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ([gestureRecognizer isEqual:self.panGesture]) {
        if (gestureRecognizer.numberOfTouches > 0) {
            CGPoint translation = [self.panGesture velocityInView:self.collectionView];
            return fabs(translation.y) > fabs(translation.x);
        } else {
            return NO;
        }
    }
    return YES;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!