题 我可以使用CGAffineTransformMakeRotation将视图旋转超过360度吗?


我正在写一个iPhone应用程序,我有一个想要向外旋转的图像。

目前我的代码看起来像这样(包含在beginAnimations / commitAnimations块中):

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

但我发现,如果我尝试将旋转角度更改为4 * M_PI,它根本不会旋转。是否可以使用CGAffineTransformRotate进行720˚旋转,还是必须切换到其他技术?

如果我必须切换到另一种技术,你会建议使用另一个线程(或计时器)来自己动画,还是OpenGL会更好?

谢谢,
布莱克。


28
2018-02-12 18:52


起源




答案:


您可以按一定数量的弧度旋转视图,无论它是小于完整旋转还是完整旋转的多倍,而不必将旋转分割成碎片。例如,以下代码将每秒一次旋转视图达指定的秒数。您可以轻松地修改它以按一定数量的旋转或某些弧度旋转视图。

- (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"];
}

64
2017-09-14 19:39



这很有效。感谢您发布并坚持评论其他人的帖子!我正准备拆分我的动画! - Dimitris
我曾经把它们分开,这似乎不对。 - mahboudz
确保你为transform.rotation.z执行此操作。我试图在使用CATransform3DMakeRotation进行转换时遇到问题。当我使用make旋转功能时,我一直遇到“万向节锁定”。当我使用如上所述的transform.rotation.z时,它的工作效果非常好! - Jay
这很棒。但似乎“轮换”结果是“轮换/秒”。还是非常有用的。我想在其他轴上旋转它的最简单方法是添加单独的动画,只需更改键路径? - Jonny
谢谢,这节省了我的培根 - Phillipus


你可以,但你需要将动画分成半圆旋转。我提供了一个这样的例子来回应 这个问题,使用应用于视图下方图层的重复CABasicAnimation。正如我在那里建议的那样,将这些半旋转作为CAKeyframeAnimation的一部分可能是更好的结构方式,因为动画会更平滑(在我的例子中,在半旋转之间有轻微的故障),你可以做开始和结束时加速/减速都很好。


5
2018-02-12 19:53



凉。这似乎做了我所希望的,我想我也可以添加一个缩放变换,并自己回到我的班级通知。谢谢! - bwinton
说你必须将动画分成半圆旋转是不正确的。看到我的回答。 - mahboudz
如果您依赖CATransform3D作为动画的值,那么您就是这样做的。我没有想过你的方法,使用Core Animation为转换结构字段提供的keypath扩展。你是对的,这可能是一个更清洁的方法来解决这个问题。 - Brad Larson♦


标题回答:是的,CGAffineTransform可以旋转360度以上。
回答问题:是的,但你不能动画它,因为没有任何动画。

记住这一点 仿射变换是一个矩阵,旋转矩阵包含正弦和余弦数 预先计算。就像你说的那样:

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];

现在,让我们回顾一些示例值 cos 和 sin

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

记得, 矩阵不包含角度 - 它只包含余弦和正弦。并且这些值不会从一个圆的倍数变为另一个。因此,没有什么可以动画的。

(注意,Calculator.app给出cos(xπ)和sin(xπ)的错误结果。试试Grapher, 计算, 要么 谷歌。)

您需要将动画拆分为圆形的分数。半圈布拉德拉森建议会做得很好。


5
2018-02-12 22:01



您不必拆分动画。看到我的回答。 - mahboudz