2012-05-04 79 views
10
[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会扭转方向,但显然不是?

回答

12

角度是一样的。要走完整圈你需要2 * Pi,所以半个圈就是Pi。如果你采用-Pi,它会在同一点结束。

编辑:如果你需要使它顺时针旋转,你可以稍微离开-Pi。例如,而不是-M_PI使用-3.141593。

+0

我同意但我需要顺时针旋转180度。什么是最好的方式来激活这个?干杯 – geminiCoder

+1

那么它会以最短的方向旋转。如果精度不是一个很大的问题,你可以旋转到略低于或高于180度。这是一个快速和肮脏的修复,但可能会工作。 – RadicalRaid

+0

刚刚看到您的编辑。它工作得很好,但看起来有点不完美。 – geminiCoder

2

下面是苹果文档中的一段引文“在iOS中,正值指定逆时针旋转,负值指定顺时针旋转。”你有没有试过这样做:

squareLayer.affineTransform = CGAffineTransformRotate(currentTransform, -M_PI); 

这就是我曾经做过的所有顺时针旋转过去。

+0

是的,这是问题所在。正如你在上面的代码中看到的,这不起作用。不知道为什么? – geminiCoder

3

我对核心animatinon的体验与苹果报价不一致。我发现唯一重要的是最终的角度值。正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]; 
7

恰好碰到了这样的重复计数尽管@ 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); 
       }]; 
0

同意邓肯和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 

} 
1

编辑:不是-M_PI使用-3 * M_PI,反时针

,并删除“ - ”符号的方向相反。

相关问题