Question

I want to rotate a view around the right edge of the screen, like a door opening. This is what I have so far:

CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0f/500;
view.layer.transform = CATransform3DRotate(transform, kDegreesToRadians(90), 0, 1, 0);
[UIView animateWithDuration:2.0f animations:^{
     view.layer.transform = transform;
} completion:nil];

I'm not totally solid on CATranforms yet or matrices for that matter so if someone could push me in the right direction, it'd be much appreciated!

Was it helpful?

Solution

UIView animations are for animating the properties of a view, not for animating layers. To the best of my knowledge, you can't animate a view's layer using a UIView animateWithDuration: call.

You'll need to create a CABasicAnimation and add it to your view's layer yourself.

It's been a while since I've done CAAnimations, but let's see what I can dig up:

As atxe says, you should move the layer's anchor point to 1,.5 before doing this animation, so it rotates around the right edge.

Here is some code from our "Kevin & Kell" cartoon app, that does an animation of a door swinging open on it's hinge:

//Open the door.
rotateAnimation = [CABasicAnimation animation];
rotateAnimation.keyPath = @"transform";
rotateAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];

//Pivot on the right edge (y axis rotation)
theTransform = CATransform3DIdentity;
  theTransform.m34 = -1/100.0;
  theTransform = CATransform3DRotate(theTransform, degreesToRadians(70), 0, 1, 0);


rotateAnimation.toValue = [NSValue valueWithCATransform3D:theTransform];

rotateAnimation.duration = 0.5;

// leaves presentation layer in final state; preventing snap-back to original state
rotateAnimation.removedOnCompletion = NO;
rotateAnimation.fillMode = kCAFillModeBoth; 

rotateAnimation.repeatCount = 0;
rotateAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
rotateAnimation.delegate = self;
[treeDoorImageView.layer addAnimation:rotateAnimation forKey:@"transform"];

The transform logic is all but identical to yours (I use an m34 value of -1/100 for a more exaggerated 3D effect. Your -1/500 setting is more normal.)

Note that instead of trying to do the animation from a UIView animation block, I create a CABasicAnimation, and set it's fromValue and toValue properties to the starting and ending transform values.

You should be able to use this code as a starting-point for your animation.

OTHER TIPS

You need to use CAAnimation, not UIView block animation.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
animation.duration = 2;
animation.fromValue = [NSValue valueWithCATransform3D:view.layer.transform]; // From the existing transform.
animation.toValue = [NSValue valueWithCATransform3D:transform]; // To the new one.

view.layer.transform = transform; // Set the new transform.
[view.layer addAnimation:animation forKey:@"door"]; // Animate visual change.

Also, as axte pointed out, you will have to set anchorPoint of the layer to (1, 0.5) to apply rotation around right edge of the layer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top