iPhoneSDK Setting CALayer.transform does not work after animation is finished
I have a CALayer object. In viewDidLoad: I set a transform to it using layer.transform = CATransform3DRotate(CATransform3DIdentity, M_PI/8.0, 0, 0, 1);
This works.
After loading, I apply a CAKeyframeAnimation
to animate the rotation of that layer. It also works and animation finishes correctly. To prevent the layer from removing the animation after completion I use
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
All of this works fine. But a problem occurs when I try to change the tr开发者_JAVA技巧ansform again (without animation) layer.transform = CATransform3DRotate(CATransform3DIdentity, M_PI/8.0, 0, 0, 1);
. Nothing happens. Layer doesn't change its transform to what I have specified. If I run the animation again, the animation will happen. But cannot change the transform property without animation.
Any help is appreciated..
First of all, why are you avoiding removing the animation upon completion? You don't need these two lines,
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
since you are actually setting the layer's transform property. Those two lines are what you would use if all you wanted was the final visual state after the animation while keeping the transform the same as the original (which frankly I've never had a use for).
The next thing you have to realize is that you are setting the transform to the same value twice. Setting the transform on a layer is not additive by default. What I mean is that while you are expecting it to take your first transform and concatenating the same transform again from the final transform state, it doesn't work that way with the code you're using. You won't see a change because you're setting the state to the state it already has.
I haven't tried it, but I think that you could probably take the first transform and concatenate the new one. Something like:
layer.transform = CATransform3DRotate(layer.transform, M_PI/8.0, 0, 0, 1);
Notice how I'm starting from the current transform on the layer (first parameter of CATransform3DRotate), instead of identity. Give that a try. If it doesn't work, try something like:
layer.transform = CATransform3DConcat(layer.transform,
CATransform3DMakeRotation(M_PI/8.0, 0, 0, 1));
OK, I managed to get this working.
What I did was setting the layer.tranform
just after calling [layer addAnimation:]
. In that way, after the animation is finished, the layer will stay in the desired position as it is. Here is my code:
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.repeatCount = 1;
animation.duration = 3.0;
animation.fromValue = [NSNumber numberWithDouble:currentRotationAngle];
animation.toValue = [NSNumber numberWithDouble:newRotationAngle];
[layer addAnimation:animation forKey:@"rotationAnimation"];
[layer setAffineTransform:CGAffineTransformMakeRotation(newRotationAngle)];
The problem I had was using layer.removedOnCompletion
and layer.fillemode
. I don't have to use them. In the new way the layer will display the layer using the layer.transform
after animation is complete. CAAnimations
only update the layer's presentationLayer (which maintains the layer's visual state) while animating. When the animation is finished, it will revert the layer's visual state to the one imposed by layer.transform
.
精彩评论