Limit UIView movement to only vertical or horizontal axis

非 Y 不嫁゛ 提交于 2019-12-07 19:21:23

问题


I'm using a PanGestureRecognizer and in the UIGestureRecognizerStateChanged I let a view on the screen be moved by the users finger. I'm using that for a Tinder like swipe away gesture and I now want to limit the movement of the view to either the horizontal axis or the vertical axis, whatever direction the user started to swipe. I've been searching up and down but didn't find anything suitable here.

Is there any clever way to limit the axis movement, based on which direction the user started to swipe the view?

Thanks a bunch!

Update: Here's the current code that moves the view:

- (void)dragged:(UIPanGestureRecognizer *)gestureRecognizer
{
    CGFloat xDistance = [gestureRecognizer translationInView:self].x;
    CGFloat yDistance = [gestureRecognizer translationInView:self].y;
//    xDistance = 0;

    [parentView dragged:yDistance];

    switch (gestureRecognizer.state) {
        case UIGestureRecognizerStateBegan:{
            self.originalPoint = self.center;
            break;
        };
        case UIGestureRecognizerStateChanged:{
            CGFloat rotationAngel = 0;
            CGFloat scale = 1;//MAX(scaleStrength, 0.93);
            CGAffineTransform transform = CGAffineTransformMakeRotation(rotationAngel);
            CGAffineTransform scaleTransform = CGAffineTransformScale(transform, scale, scale);
            self.transform = scaleTransform;
            self.center = CGPointMake(self.originalPoint.x + xDistance, self.originalPoint.y + yDistance);
            ...
            break;
        };
        case UIGestureRecognizerStateEnded: {
            float moveDistAction = 60;
            if (yDistance > moveDistAction) {
                // view swiped down
                ...
            } else if (yDistance < -moveDistAction) {//100 150
                // view swiped up 
                ...
            } else {
                // dragging cancelled
                ...
            }
            break;
        };
        case UIGestureRecognizerStatePossible:break;
        case UIGestureRecognizerStateCancelled:break;
        case UIGestureRecognizerStateFailed:break;
    }
}

回答1:


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



回答2:


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...



来源:https://stackoverflow.com/questions/28503095/limit-uiview-movement-to-only-vertical-or-horizontal-axis

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