How to limit pan gesture area?

12,497

Solution 1

Try This

-(void)handleMovementView:(UIPanGestureRecognizer *)recognizer
{
CGPoint movement;

if(recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged || recognizer.state == UIGestureRecognizerStateEnded)
{
    CGRect rec = recognizer.view.frame;
    CGRect imgvw = self.imgViewCrop.frame;
    if((rec.origin.x >= imgvw.origin.x && (rec.origin.x + rec.size.width <= imgvw.origin.x + imgvw.size.width)))
    {
        CGPoint translation = [recognizer translationInView:recognizer.view.superview];
        movement = translation;
        recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
        rec = recognizer.view.frame;

        if( rec.origin.x < imgvw.origin.x )
            rec.origin.x = imgvw.origin.x;

        if( rec.origin.x + rec.size.width > imgvw.origin.x + imgvw.size.width )
            rec.origin.x = imgvw.origin.x + imgvw.size.width - rec.size.width;

        recognizer.view.frame = rec;

        [recognizer setTranslation:CGPointZero inView:recognizer.view.superview];
        [self handleMovementForHandlers:movement];
    }
}
}

Solution 2

Instead of manually computing whether the points are within the view's bounds, use CGRectContainsPoint(rect, point). This is what works for me, and I like it because it's shorter and more readable:

func handlePan(pan: UIPanGestureRecognizer) {
    switch pan.state {
    case .Began:
        if CGRectContainsPoint(self.pannableView.frame, pan.locationInView(self.pannableView)) {
            // Gesture started inside the pannable view. Do your thing.
        }
}

Solution 3

Expanding on @Matt Quiros' answer, and in Swift 3 / 4:

func shouldRespondToGesture(_ gesture: UIGestureRecognizer, in frame: CGRect) -> Bool {
    return gesture.state == .began && frame.contains(gesture.location(in: self.view))
}
Share:
12,497
Heena
Author by

Heena

Updated on June 04, 2022

Comments

  • Heena
    Heena almost 2 years

    I am having my UIImageView onto which I am having another UIView rectangle. By applying pan gesture to UIView rectangle it gets outside of UIImageView also. I don't want to be drag outside of UIImageView

    I have tried below code but it is not working that way

    -(void)handleMovementView:(UIPanGestureRecognizer *)recognizer
    {
        CGPoint movement;
    
        if(recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged || recognizer.state == UIGestureRecognizerStateEnded)
        {
            CGRect rec = recognizer.view.frame;
            CGRect imgvw = self.imgViewCrop.frame;
            if((rec.origin.x >= imgvw.origin.x && (rec.origin.x + rec.size.width <= imgvw.origin.x + imgvw.size.width)))
            {
                CGPoint translation = [recognizer translationInView:recognizer.view.superview];
                movement = translation;
                recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
                [recognizer setTranslation:CGPointZero inView:recognizer.view.superview];
                [self handleMovementForHandlers:movement];
            }
        }
    
    }
    

    If i apply Pan slowly it applies this condition but when i go fast it went outside of ImageView

  • Sumurai8
    Sumurai8 over 10 years
    Please do not beg in an answer for 'likes'.
  • krishan kumar
    krishan kumar almost 5 years
    if you feel laggy while moving then, try min,max function limit area. For example: var newCenter = CGPoint(x: x + translation.x, y: y + translation.y) newCenter.x = min(maxXcenter,newCenter.x) newCenter.x = max(minXCenter,newCenter.x) newCenter.y = min(maxYCenter,newCenter.y) newCenter.y = max(minYCenter,newCenter.y)