开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜