Alex Stone
Alex Stone

Reputation: 47364

iPhone4 iOS5 UIRotationGestureRecognizer, how to remember rotation offset for subsequent rotations?

I'm trying to create a knob-like behavior in one of my views with a UIRotationGestureRecognizer. This works, and positions the view as expected. However, every single time a gesture is performed, the rotation of the recognizer resets, so the knob starts at 0 every time.

How can I remember the last rotation of the UIRotationGestureRecognizer to let the user adjust the knob UIView without resetting it every single time?

I'm trying to make the recognizer start calculating rotation changes from the view's last known rotation:

knob starts at 0, recognizer is at 0
recognizer is rotated to 45 degrees
recognizer stops rotating
the knob is left at 45 degrees //this is already happening with the provided code snippet

next touch:

//this is what's is happening
recognizer starts at 0, rotates the knob back to 0
//I want it to be:
recognizer starts at 45, rotates the knob as in the example above. 


- (IBAction)rotateView:(id)sender {

    if([sender isKindOfClass:[UIRotationGestureRecognizer class]])
    {
            UIRotationGestureRecognizer* recognizer = sender;

            CGAffineTransform transform = CGAffineTransformMakeRotation([recognizer rotation]);
            rotatingView.transform = transform;
    }

}

Upvotes: 1

Views: 2053

Answers (3)

atreat
atreat

Reputation: 4413

You have to make sure that you reset the rotation after the transform. Otherwise they will stack on top of each other and you get the "interesting" behavior.

rotatingView.transform = CGAffineTransformScale(rotatingView.transform, recognizer.scale, recognizer.scale);
[recognizer setRotation:0];   // this line

You should also do this for any translation or scaling transformations that you may do when handling gestures. The methods there are:

[recognizer setScale:1];
[recognizer setTranslation:CGPointZero inView:recognizer.view.superview];

Upvotes: 1

tidwall
tidwall

Reputation: 6949

You should be able to get the current rotation of the rotatingView from it's transform property. Store this value into a savedRotation variable when the gesture begins. Make sure to assign a delegate to handle the gestureRecognizerShouldBegin callback.

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)recognizer
{
    savedRotation = atan2(rotatingView.transform.b, rotatingView.transform.a);
    return YES;
}

- (void)rotateView:(UIRotationGestureRecognizer*)recognizer
{
    rotatingView.transform = CGAffineTransformMakeRotation(recognizer.rotation+savedRotation);
}

Upvotes: 3

tarmes
tarmes

Reputation: 15442

Transform the transform:

rotatingView.transform = CGAffineTransformRotate(rotatingView.transform, [recognizer rotation]);

Upvotes: 1

Related Questions