Limit UIView movement to only vertical or horizontal axis

99封情书 提交于 2019-12-06 07:53:07

In gestureRecognizerShouldBegin: you can know that direction:

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer {
    CGPoint translation = [gestureRecognizer translationInView:self.view];
    self.isVerticalPan = fabs(translation.y) > fabs(translation.x); // BOOL property

    return YES;
}

And then on the UIGestureRecognizerStateChanged you could do something like this, based on isVerticalPan property:

CGPoint translation = [gesture translationInView:self.view];
CGPoint displacement = (self.isVerticalPan) ? CGPointMake(0, translation.y) : CGPointMake(translation.x, 0);

self.viewToMove.transform = CGAffineTransformMakeTranslation(displacement.x, displacement.y);

You can do this by implementing the gestureRecognizerShouldBegin: delegate method. In the following implementation, I am checking for a roughly 20 degree horizontal swipe. But, you could check for either a horizontal or vertical swipe. (I would use some small angle, as it's very difficult for the user to move in exactly a straight line.)

- (BOOL) gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    // Ensure that the user is only panning mostly horizontally
    // This allows the view to be placed in a scrollview that scrolls vertically
    // Up/Down drags in the body of the view will be passed to the scroll view
    if (gestureRecognizer == self.panGesture) {

        CGPoint velocity = [self.panGesture velocityInView:self.panGesture.view];

        double radian = atan(velocity.y/velocity.x);
        double degree = radian * 180 / M_PI;

        double thresholdAngle = 20.0;
        if (fabs(degree) > thresholdAngle) {
            return NO;
        }
    }
    return YES;
}

Disclaimer: I'm pretty sure I found this solution somewhere here, but I couldn't find it. So, apologies to the original solver of this...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!