我想做一个无限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 * 1
,M_PI * 2
...
但结果是从0
到M_PI
,然后从M_PI
到0
的旋转。
我可以通过 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
来制作动画效果会更清晰。
关于ios - CATransaction旋转层360度怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21761184/