elijah
elijah

Reputation: 2924

Reverse a CGAffineTransform rotation on a custom UIView with UIBezierPaths

I have a custom UIView. It initializes two rectangular UIBezierPaths, and in drawRect it simply fills these two paths.

This view is placed on a button. When the button is clicked, a rotation is applied to it inside an animateWithDuration block:

icon.transform = CGAffineTransformMakeRotation(M_PI*-0.25);

This works great.

When the button is clicked again, I am trying to make the view rotate back to it's original orientation (reverse the rotation). I have tried:

icon.transform = CGAffineTransformInvert(icon.transform);
icon.transform = CGAffineTransformMakeRotation(M_PI*0.25);
icon.transform = CGAffineTransformIdentity;

... and a number of other variations, but none of them seem to work. Instead, the view is distorted until it's no longer visible -- sorta stretched to nothing. Sometimes, reapplying the first transform brings it back but with other reversals it doesn't.

What am I doing wrong?

Upvotes: 1

Views: 4745

Answers (1)

Abhishek Singh
Abhishek Singh

Reputation: 6166

In ios the transform is always relative, so once transformation is done, the next transformation should be relative to the previous transformation. You can simply change the frame of the view and revert it back to normal on second button click. On even clicks you will have to revert back the frame. Implement the following code. You can use the block level code if you feel comfortable with it as it is the new norm.

int noOfClicks = 0;

-(IBAction)yourBtnAction:(id)sender
{
    noOfClicks++;

    if(noOfClicks %2 != 0)
    {
        [UIView beginAnimations:@"Rotate" context:nil];
        [UIView setAnimationDuration:1.0];
        [UIView setAnimationDelegate:self];
        CGRect frame=yourView.frame;
        frame.origin.y+=20;
        yourview.frame=frame;
        [UIView commitAnimations];
    }
    else
    {
        [UIView beginAnimations:@"Rotate" context:nil];
        [UIView setAnimationDuration:1.0];
        [UIView setAnimationDelegate:self];
        CGRect frame=yourView.frame;
        frame.origin.y-=20;
        yourview.frame=frame;
        [UIView commitAnimations];
    }
}

If you don't want to make so many change you can use following to revert back but employing same logic:

[UIView beginAnimations:@"Rotate back" context:nil];
[UIView setAnimationDuration:1.0];

yourView.transform = CGAffineTransformIdentity;

[UIView commitAnimations];

Upvotes: 1

Related Questions