简体   繁体   English

将UIView旋转360度以上

[英]Rotating a UIView through 360 degrees and more

I'm pretty confused by radians at the best of times, so I tend to work in degrees when I'm rotating UIViews. 最好的情况下,我对弧度感到困惑,因此在旋转UIView时我倾向于以度为单位工作。 So far I've been using the following formula to convert degrees to radians: 到目前为止,我一直在使用以下公式将度数转换为弧度:

#define radians(x) (M_PI * x / 180.0)

So far so good. 到现在为止还挺好。 The problem comes when I have a UIView on the screen which the user is rotating through 360 degrees and more, and I want to display on the screen how many degrees the image has been rotated. 当我在用户旋转360度及以上的屏幕上显示UIView时,就会出现问题,并且我想在屏幕上显示图像旋转了多少度。 I have this and it works fine up to 180 degrees: 我有这个,它可以在180度以下正常工作:

float rot = [recognizer rotation];
[self.steeringWheel setTransform:CGAffineTransformRotate([self.steeringWheel transform], (rot))]; // turn wheel

CGFloat radians = atan2f(steeringWheel.transform.b, steeringWheel.transform.a); 
CGFloat degrees = radians * (180 / M_PI);

self.degreesBox.text = [NSString stringWithFormat:@"%1.0f", degrees]; // show degrees of rotation on screen

After 180 degrees, my read out changes to -179, -178 etc all the way back to zero. 180度后,我的读数更改为-179,-178等,一直回到零。 Instead, I want it to continue counting on up to 359 (and then back to zero, 1, 2, etc if possible). 相反,我希望它继续计数到359(如果可能,然后返回零,1、2等)。

I could use a formula that adds 2 to 179, 3 to 178 etc to get the right amount, but this would not work when I then go and turn the wheel in the opposite direction (a -1 degree turn would read out as 359, when really I want it to read out as either 1 or -1). 我可以使用将2加到179,将3加到178等的公式来获取正确的量,但是当我随后以相反的方向旋转车轮时,此方法将不起作用(-1度的旋转会显示为359,实际上,我希望它以1或-1的形式读出。

I hope this makes sense. 我希望这是有道理的。 Basically, I want to read how much the wheel has turned in each direction from the start point. 基本上,我想阅读车轮从起点到每个方向的旋转量。 What I'm getting at the moment is a reading of how many degrees back to the start point via the shortest route. 目前,我得到的是通过最短路线返回起点的度数的读数。

Try this code: 试试这个代码:

CGFloat radians = atan2f(steeringWheel.transform.b, steeringWheel.transform.a); 
if (radians < 0.0) radians += 2 * M_PI;
CGFloat degrees = radians * (180 / M_PI);

EDIT: 编辑:

After rereading your question i saw where your problem really is. 重读您的问题后,我看到了您的问题的真正所在。 atan2 will always return results in range (−π, π]. atan2将始终返回范围(-π,π]中的结果。

And it looks you want the stearing wheel to be able to rotate a full circle to the left and a full cricle to the right. 而且看起来您希望滚轮能够向左旋转一个完整的圆圈,向右旋转一个完整的冰柱。 You can solve this by comparing new angle to the old angle so you'd know if user is rotating the wheel in CW or CCW. 您可以通过将新角度与旧角度进行比较来解决此问题,从而知道用户是在顺时针还是逆时针方向旋转车轮。

You can also set a flag when user rotates the wheel left (CCW) from starting (idle) position to manage sign accordingly. 当用户从开始(怠速)位置向左旋转车轮(CCW)以相应地管理标志时,您还可以设置标志。

Swift 3 : 迅捷3
Animation with nested closure is better than animation delay block. 具有嵌套闭包的动画比动画延迟块更好。

UIView.animate(withDuration: 0.5, animations: { 
     button.transform = CGAffineTransform(rotationAngle: (CGFloat(Double.pi)) 
}) { (isAnimationComplete) in

           // Nested Block
            UIView.animate(withDuration: 0.5) { 
               button.transform = CGAffineTransform(rotationAngle: (CGFloat(Double.pi * 2))
           }    
     }

Animation with delay and options: 具有延迟和选项的动画:

// Rotation from 0 to 360 degree    
UIView.animate(withDuration:0.5, animations: { () -> Void in
      button.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
})

// Rotation from 180 to 360 degree
UIView.animate(withDuration: 0.5, delay: 0.45, options: .curveEaseIn, animations: { () -> Void in
       button.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi * 2))
}, completion: nil)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM