当我想要顺时针方向时,为什么我的旋转只会逆时针方向?

时间:2012-05-04 09:08:14

标签: objective-c ios core-animation

[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会扭转方向,但显然不是?

8 个答案:

答案 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选项很重要,否则您必须手动指定相对的开始时间和持续时间