Search code examples
iphoneobjective-ccocoaquartz-graphics

How to rotate view around anchor point multiple times


I am truly stumped with a problem I am having with rotating a view. I am trying to make several views rotate around an arbitrary point (like a touch).

First of all, without fully explaining (just take my word for it) I would just like to say that due to the complexity of my view layout and what I need to accomplish, the "cheat" method, as it is sometimes called, where you add all the views that need to rotate to a bigger view and rotate that view, won't work for me.

I am changing the anchor point of the layer so that my view(s) will rotate around the point of a double tap. However, something that I can't quite figure out keeps throwing me for a loop. When I rotate it once (say 90º), and rotate it 90º again, instead of ending up at 180º (what you would expect), I am ending up at 270º (or some other weird number).

I will try and post enough code so that you can see what I am saying (and hopefully help me).

I have one instance variable declared in the .h

UIView *theView;

Here is the .m (you will need to import the QuartzCore framework)

- (void)viewDidLoad {
    [super viewDidLoad];

    theView = [[UIView alloc]initWithFrame:CGRectMake(140, 40, 40, 40)];
    theView.backgroundColor = [UIColor blueColor];

    [self.view addSubview:theView];

}

#define DegreesToRadians(x) ((x) * M_PI / 180.0)

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];

    CGPoint touchLocation = [touch locationInView:self.view];

    if ([touch tapCount]==2) {

        CGFloat xValue = ((touchLocation.x - theView.frame.origin.x)/theView.frame.size.width);
        CGFloat yValue = ((touchLocation.y - theView.frame.origin.y)/theView.frame.size.height);

      CGRect priorRect = theView.frame;
        theView.layer.anchorPoint = CGPointMake(xValue, yValue);
        theView.frame = priorRect;

        static float rotationValue = 0.0f;
        rotationValue += 90.0f;

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:1.0f];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        theView.transform = CGAffineTransformRotate(theView.transform, DegreesToRadians(rotationValue));
        [UIView commitAnimations];

    }
}

I have tried this with every different configuration I could possibly think of, so this example is just what I threw together because it seemed to be pretty concise. Anyway, PLEASE HELP ME!!!


Solution

  • The anchor point needs to be set appropriately.

    Setting anchor point for UIView layer

    If you only want to rotate at 90 degrees a tap, then don't aggregate the rotation, it rotationValue should always be 90 degrees.

    If you want it to rotate a greater amount each time, then you'll have jumping issues, so you should see the following link for how to do that properly.

    rotate a UIView around its center but several times