Can I use CGAffineTransformMakeRotation to rotate a view more than 360 degrees?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-17 03:56:12

问题


I'm writing an iPhone app, and I've got an image which I'ld like to have swirl outwards.

Currently my code looks like this (wrapped in a beginAnimations/commitAnimations block):

scale = CGAffineTransformScale(CGAffineTransformIdentity, 5.0f, 5.0f);
swirl = CGAffineTransformRotate(scale, M_PI);
[player setTransform:swirl];    
[player setAlpha:0.0f];

But I find that if I try to change the angle of the rotation to, say, 4*M_PI, it doesn't rotate at all. Is it possible to get a 720˚ rotation using CGAffineTransformRotate, or do I have to switch to another technology?

If I have to switch to another technology, would you recommend using another thread (or a timer) to do the animation myself, or would OpenGL be a better route to go?

Thanks,
Blake.


回答1:


You can rotate a view, by some number of radians, regardless of whether it is less than a full rotation or many multiples of a full rotation, without having to split the rotation into pieces. As an example, the following code will spin a view, once per second, for a specified number of seconds. You can easily modify it to spin a view by a certain number of rotations, or by some number of radians.

- (void) runSpinAnimationWithDuration:(CGFloat) duration;
{
    CABasicAnimation* rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ];
    rotationAnimation.duration = duration;
    rotationAnimation.cumulative = YES;
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

    [myView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}



回答2:


You can, but you will need to split your animation into half-circle rotations. I provide an example of this in response to this question, using a repeating CABasicAnimation applied to the layer underneath the view. As I suggest there, doing these half-rotations as parts of a CAKeyframeAnimation would probably be the better way to structure this, because the animation would be smoother (there's a slight hitch in between half-rotations in my example), and you could do a nice acceleration / deceleration at the start and end.




回答3:


Answer to title: Yes, CGAffineTransform can rotate more than 360 degrees just fine.
Answer to question: Yes, but you cannot animate it because there is nothing to animate.

Remember that the affine transformation is a matrix, and that a rotation matrix contains the sine and cosine numbers precomputed. It's as if you said:

CGFloat angle = 4.0 * M_PI;
NSAffineTransformStruct matrix = {
    .m11 = cos(angle),
    .m12 = sin(angle),
    .m21 = -sin(angle),
    .m22 = cos(angle),
    .tx = 0.0,
    .ty = 0.0
};
NSAffineTransform *transform = [NSAffineTransform transform];
[transform setTransformStruct:matrix];

Now, let's review some sample values for cos and sin:

  • cos(0π) = 1
  • sin(0π) = 0
  • cos(2π) = 1
  • sin(2π) = 0
  • cos(4π) = 1
  • sin(4π) = 0

Remember, the matrix doesn't contain the angle -- it only contains the cosine and sine. And those values don't change from one multiple of a circle to another. Therefore, there is nothing to animate.

(Note that Calculator.app gives wrong results for cos(xπ) and sin(xπ). Try Grapher, calc, or Google.)

You will need to split the animation into fractions of a circle. The half-circles Brad Larson suggested will do just fine.



来源:https://stackoverflow.com/questions/542739/can-i-use-cgaffinetransformmakerotation-to-rotate-a-view-more-than-360-degrees

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!