[CATransaction begin];
[CATransaction setAnimationDuration:5];
CGAffineTransform currentTransform = squareLayer.affineTransform;
CGFloat angle = M_PI;
squareLayer.affineTransform = CGAffineTransformRotate(currentTransform, angle);
[CATransaction commit];
和
[CATransaction begin];
[CATransaction setAnimationDuration:5];
CGAffineTransform currentTransform = squareLayer.affineTransform;
CGFloat angle = (M_PI * -1);
squareLayer.affineTransform = CGAffineTransformRotate(currentTransform, angle);
[CATransaction commit];
我原以为-1会扭转方向,但显然不是?
答案 0 :(得分:14)
角度是一样的。要完整的圆圈你需要2 * Pi,所以半圈是Pi。如果你拿-Pi它会在同一点结束。
编辑:如果你需要顺时针转动,你可以略微离开-Pi。而不是-M_PI,例如使用-3.141593。
答案 1 :(得分:9)
刚刚遇到这个问题,虽然@ radicalraid的解决方案工作正常,但我更喜欢在旋转之前调整起始角度,然后旋转到小于所需终点的角度。此外,您可以使用动画块为CALayer
变换设置动画。
我的代码:
// iOS will rotate the shortest distance to the end angle,
// using counter-clockwise if equal.
// Force the rotation to open clockwise and close counter-clockwise by bumping
// the initial angle
CGFloat startRadians, endRadians;
if (isOpening) {
startRadians = 0.01f;
endRadians = M_PI;
}
else {
startRadians = M_PI - 0.01f;
endRadians = 0.0f;
}
self.myImageView.layer.affineTransform = CGAffineTransformMakeRotation(startRadians);
[UIView animateWithDuration:0.3f
animations:^{
self.myImageView.layer.affineTransform = CGAffineTransformMakeRotation(endRadians);
}];
答案 2 :(得分:5)
我对Core animatinon的经验与Apple引用不一致。我发现,唯一重要的是最终的角度值。正pi和负pi旋转产生相同的变换矩阵,因此无论如何系统只是反时钟。
我在特定方向上进行旋转或完整旋转360度所做的是使用类型transform.rotation.z创建显式CABasicAnimation,填充模式设置为kCAFillModeForwards,并且仅提供toValue。这会导致动画从之前的值开始。然后,您可以设置一个旋转,该旋转是您所需旋转总量的偶数部分,并给它重复计数。
例如,下面的代码创建一个旋转5个四分之一圈或450度的动画。如果你想顺时针旋转180度,你可以旋转pi / 2,重复次数为2.对于逆时针,使用-pi / 2,重复次数为2.
CABasicAnimation* rotate = [CABasicAnimation animationWithKeyPath:
@"transform.rotation.z"];
rotate.removedOnCompletion = FALSE;
rotate.fillMode = kCAFillModeForwards;
//Do a series of 5 quarter turns for a total of a 1.25 turns
//(2PI is a full turn, so pi/2 is a quarter turn)
[rotate setToValue: [NSNumber numberWithFloat: -M_PI / 2]];
rotate.repeatCount = 5;
rotate.duration = duration/rotate.repeatCount * 2 ;
rotate.beginTime = start;
rotate.cumulative = TRUE;
rotate.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionLinear];
答案 3 :(得分:3)
编辑:代替-M_PI使用-3 * M_PI,用于逆时针
并删除相反方向的“ - ”符号。
答案 4 :(得分:2)
看一下上一个问题:Force clockwise/anticlockwise rotation for a CABasicAnimation of a UIImageView代码有点不同但确实有用。
答案 5 :(得分:2)
以下是苹果文档的引用“在iOS中,正值表示逆时针旋转,负值表示顺时针旋转。”你试过这样做了吗?
squareLayer.affineTransform = CGAffineTransformRotate(currentTransform, -M_PI);
这就是我以前用过的所有顺时针旋转。
答案 6 :(得分:0)
同意Duncan和XJones。最终价值似乎很重要。然后,CA将找到最短路径。
使用XJones的想法。这似乎对我有用:
private let angleRadians = CGFloat(M_PI)
private let angleRadiansOffset = CGFloat(0.1 * M_PI/180.0)
let turnAngle = angleRadians - angleRadiansOffset;
//pre-rotate by an 'invisible amount', to force rotation in the same direction every time
primView.layer.transform = CATransform3DRotate(primView.layer.transform, angleRadiansOffset, 0.0, 1.0, 0.0)
UIView.animateKeyframesWithDuration(duration, delay: 0, options: [.BeginFromCurrentState], animations: { () -> Void in
UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0.8, animations: { () -> Void in
//now we will complete the rotation to the correct end value
primView.layer.transform = CATransform3DRotate(primView.layer.transform, turnAngle, 0.0, 1.0, 0.0)
})
//... other code ....
}) { (finished) -> Void in
}
答案 7 :(得分:0)
这是我用来使其始终沿顺时针if endAngle > startAngle
和逆时针if startAngle > endAngle
旋转的功能。 (例如,动画绝不能“跨越2 * pi线”)
private func rotate(view: UIView, from startAngle: CGFloat, to endAngle: CGFloat) {
let midAngle = (startAngle.truncatingRemainder(dividingBy: 2 * .pi) + endAngle.truncatingRemainder(dividingBy: 2 * .pi)) / 2
UIView.animateKeyframes(withDuration: UIView.inheritedAnimationDuration, delay: 0, options: .calculationModeCubicPaced, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0) {
view.transform = CGAffineTransform(rotationAngle: midAngle)
}
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0) {
view.transform = CGAffineTransform(rotationAngle: endAngle)
}
}, completion: nil)
}
您也可以从另一个UIView.animate块内部调用它,以使其与其他事物一起进行动画处理。例如:
UIView.animate(withDuration: 1) {
rotate(view: view, from: .pi * 0.25, to: 1.5 * .pi)
otherView.alpha = 1
}
使用.calculationModeCubicPaced
选项很重要,否则您必须手动指定相对的开始时间和持续时间