Krystian
Krystian

Reputation: 3423

How to animate rotated and moved UIView to its original position?

I've got an UIImageView with a pan gesture recognizer, which I move and rotate based on user action. When user lifts the finger, I want it to be animated back to its original position, here's my code:

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {

    if (recognizer.state == UIGestureRecognizerStateBegan) {
        startX = recognizer.view.center.x;
        startY = recognizer.view.center.y;
        startRotation = atan2(recognizer.view.transform.b, recognizer.view.transform.a);
        NSLog(@"Start Position %f %f %f", startX, startY, startRotation);
    } else if (recognizer.state == UIGestureRecognizerStateEnded) {

        float distance = (startX - recognizer.view.center.x) / DISTANCE_TO_ACCEPT;
        CGPoint center = recognizer.view.center;


            // animate back
            [UIView animateWithDuration:0.5 animations:^{
                NSLog(@"Position %f %f %f", recognizer.view.center.x, recognizer.view.center.y, atan2(recognizer.view.transform.b, recognizer.view.transform.a));
                NSLog(@"Destination %f %f %f", startX, startY, startRotation);
                NSLog(@"Translation %f %f %f", startX - center.x, startY - center.y, (startRotation - atan2(recognizer.view.transform.b, recognizer.view.transform.a)));

                recognizer.view.transform = CGAffineTransformRotate(CGAffineTransformTranslate(recognizer.view.transform, startX - center.x, startY - center.y), (CGFloat) (startRotation - atan2(recognizer.view.transform.b, recognizer.view.transform.a)));
            }];


    } else if (recognizer.state == UIGestureRecognizerStateChanged) {
        // move image
        CGPoint translation = [recognizer translationInView:self.view];
        recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x, recognizer.view.center.y + translation.y);
        [recognizer setTranslation:CGPointMake(0, 0) inView:self.view];

        // rotate image
        float distance = (startX - recognizer.view.center.x) / DISTANCE_TO_ACCEPT;

        // cap distance
        if (distance > 1) {
            distance = 1;
        } else if (distance < -1) {
            distance = -1;
        }

        double rotation = 15 - startRotation;
        rotation = rotation * distance;
        recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, (CGFloat) ((rotation * M_PI / 180) - atan2(recognizer.view.transform.b, recognizer.view.transform.a)));

    }

}

But it never goes to the original position. It always has some kind of offset. Further movement of the image view only makes it worse. It looks like the position is not modified during the back animation, because when I pan the image again, the start position and rotation is equal to the position and rotation it had at the end of previous movement [even though on screen the image position and rotation has changed].

What am I doing wrong here?

Thanks

Upvotes: 4

Views: 435

Answers (1)

MichK
MichK

Reputation: 3252

Try something like this in UIGestureRecognizerStateEnded state:

recognizer.view.transform = CGAffineTransformIdentity;
recognizer.view.center = CGPointMake(startX,startY);

Upvotes: 4

Related Questions