CATransaction旋转层360度奇怪

我想执行一个无限的360度旋转动画,所以我编码:

- (void)rotate { __weak typeof(self) weakSelf = self; [CATransaction begin]; [CATransaction setDisableActions:NO]; [CATransaction setCompletionBlock:^{ [weakSelf rotate]; }]; [CATransaction setAnimationDuration:1.0]; [CATransaction setAnimationTimingFunction: [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; self.squareLayer.transform = CATransform3DRotate(self.squareLayer.transform, M_PI, 0, 0, 1); [CATransaction commit]; } 

M_PI表示180度,所以我相信该层可以从0旋转到M_PI * 1M_PI * 2 ……

但事实certificate是从0M_PI的旋转,然后是M_PI0

我可以通过CABasicAnimation

 CABasicAnimation *animatin = [CABasicAnimation animationWithKeyPath:@"transform"]; animatin.duration = 1.0; animatin.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0, 0, 0, 1)]; animatin.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI, 0, 0, 1)]; animatin.repeatCount = HUGE_VALF; animatin.fillMode = kCAFillModeForwards; [self.squareLayer addAnimation:animatin forKey:@"a"]; 

上面的代码将图层完美旋转360度。

但我真的很困惑第一次实现,为什么它旋转这么奇怪?

这是一个边缘案例。 使用隐式动画,您无法说“顺时针旋转此数量”。 您只是在说“将变换设置为此值,并为该效果设置动画”。 那么,这个改变应该如何动画? 运行时必须构成一个答案,并且如何做到这一点并不明显。 M_PI的旋转变换在两个方向上都是相同的“距离”,因此它所构成的答案是任意的。 如果提供M_PI+0.1的值与M_PI-0.1的值,则可以更清楚地看到问题。 你实际得到反向结果:一个顺时针转动,另一个逆时针转动。

另一方面,使用CABasicAnimation,您有一个从值(隐式或显式)和一个到值,因此您可以表达“增加”的概念(即正差意味着顺时针转动)。 如果通过设置byValue动画制作,则更加清晰。