Search code examples
iphoneobjective-cipaddrag

How to use UIPanGestureRecognizer to move object? iPhone/iPad


There are several examples of the UIPanGestureRecognizer class. For example I have read this and I am still not able to use it...

On the nib file that I am working on I have a UIView (white rectangle on image) that I wish to drag with that class:

enter image description here

and in my .m file I have placed:

- (void)setTranslation:(CGPoint)translation inView:(UIView *)view
{
    NSLog(@"Test to see if this method gets executed");
}

and that method does not get executed when I drag the mouse across the UIView. I have also tried placing:

- (void)pan:(UIPanGestureRecognizer *)gesture
{
    NSLog(@"testing");
}

And that method does not get executed either. Maybe I am wrong but I think this methods should work like the - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event method where I just have to place that method and it will get called whenever there are touches.

What am I doing wrong? Maybe do I have to draw a connection to that method? If so how can I do that?


Solution

  • I found the tutorial Working with UIGestureRecognizers, and I think that is what I am looking for. It helped me come up with the following solution:

    -(IBAction) someMethod {
        UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
        [panRecognizer setMinimumNumberOfTouches:1];
        [panRecognizer setMaximumNumberOfTouches:1];
        [ViewMain addGestureRecognizer:panRecognizer];
        [panRecognizer release];
    }
    
    -(void)move:(UIPanGestureRecognizer*)sender {
        [self.view bringSubviewToFront:sender.view];
        CGPoint translatedPoint = [sender translationInView:sender.view.superview];
    
        if (sender.state == UIGestureRecognizerStateBegan) {
            firstX = sender.view.center.x;
            firstY = sender.view.center.y;
        }
    
    
        translatedPoint = CGPointMake(sender.view.center.x+translatedPoint.x, sender.view.center.y+translatedPoint.y);
    
        [sender.view setCenter:translatedPoint];
        [sender setTranslation:CGPointZero inView:sender.view];
    
        if (sender.state == UIGestureRecognizerStateEnded) {
            CGFloat velocityX = (0.2*[sender velocityInView:self.view].x);
            CGFloat velocityY = (0.2*[sender velocityInView:self.view].y);
    
            CGFloat finalX = translatedPoint.x + velocityX;
            CGFloat finalY = translatedPoint.y + velocityY;// translatedPoint.y + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y);
    
            if (finalX < 0) {
                finalX = 0;
            } else if (finalX > self.view.frame.size.width) {
                finalX = self.view.frame.size.width;
            }
    
            if (finalY < 50) { // to avoid status bar
                finalY = 50;
            } else if (finalY > self.view.frame.size.height) {
                finalY = self.view.frame.size.height;
            }
    
            CGFloat animationDuration = (ABS(velocityX)*.0002)+.2;
    
            NSLog(@"the duration is: %f", animationDuration);
    
            [UIView beginAnimations:nil context:NULL];
            [UIView setAnimationDuration:animationDuration];
            [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
            [UIView setAnimationDelegate:self];
            [UIView setAnimationDidStopSelector:@selector(animationDidFinish)];
            [[sender view] setCenter:CGPointMake(finalX, finalY)];
            [UIView commitAnimations];
        }
    }