我可以在Quartz 2D中为iPhone进行旋转变换时移动原点吗?

时间:2009-03-22 04:48:15

标签: iphone core-animation 2d quartz-graphics

很抱歉,如果这是显而易见的或在其他地方有所涉及,但我一直在谷歌搜索,并没有找到真正有效的解决方案。

我的问题如下:我目前正在全屏UIView中绘制图像,例如我们会说图像位于UIView的右下角。我想在该图像的中心进行旋转变换(CGAffineTransformMakeRotation),但是,默认情况下,旋转命令围绕UIView的中心旋转。结果,当我旋转时,我的图像在屏幕上移动,而不是停留在原地,并围绕自己的中心旋转。

根据我收集的内容,我需要翻译我的上下文,以便原点(UIView的中心)位于我的图像的中心,旋转,然后通过平移回原始点来恢复上下文。 / p>

以下是我最接近工作的问题,但问题是当图像旋转时,它会在旋转时向下移动。我认为这是由动画补间第一步翻译和第三步翻译而不是仅仅意识到翻译的起点和终点是相同的......

// Before this i'd make a call to a function that draws a path to a passed in context
CGAffineTransform inverseTranslation = CGAffineTransformMakeTranslation( transX, transY );
CGAffineTransform translation = CGAffineTransformMakeTranslation( -transX, -transY );
CGAffineTransform rot = CGAffineTransformMakeRotation( 3.14 );
CGAffineTransform final = CGAffineTransformConcat( CGAffineTransformConcat( inverseTranslation, rot ), translation );
// Then i apply the transformation animation like normal using self.transform = final etc etc

我也尝试过像CGContextTranslateCTM和CGContextSaveGState / UIGraphicsPushContext这样的东西,但这些似乎没什么效果。

我已经和它斗争了好几天,我目前的解决方案似乎很接近,但我不知道如何摆脱那种翻译补间。有没有人有这方面的解决方案或更好的方法来解决这个问题?

[更新] 暂时我将我的图像绘制在UIview的中心,然后将UIView.center属性设置为原点,我想旋转然后执行旋转命令。看起来像是一个黑客,但直到我能得到真正的翻译工作它是我唯一的选择。 谢谢!

4 个答案:

答案 0 :(得分:14)

duncanwilcox'答案是正确的,但他遗漏了你将视图层的锚点更改为想要旋转的点的部分。

CGSize sz = theview.bounds.size;
// Anchorpoint coords are between 0.0 and 1.0
theview.layer.anchorPoint = CGPointMake(rotPoint.x/sz.width, rotPoint.y/sz.height);
[UIView beginAnimations:@"rotate" context:nil];
theview.transform = CGAffineTransformMakeRotation( 45. / 180. * M_PI );
[UIView commitAnimations];

此处记录了这些内容:http://developer.apple.com/documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layers.html

答案 1 :(得分:7)

这也是一个选择:基础的简单改变; - )

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformTranslate(transform,-x,-y);

其中(x,y)是您喜欢的旋转中心

答案 2 :(得分:2)

旋转发生在视图图层的anchorPoint周围。 anchorPoint的默认值是中心(0.5,0.5),因此单独旋转而不进行翻译就足够了。

快速测试,这对我有用:

[UIView beginAnimations:@"rotate" context:nil];
self.transform = CGAffineTransformMakeRotation( 45. / 180. * 3.14 );
[UIView commitAnimations];

答案 3 :(得分:1)

如果你不想要动画,只需设置新的轮换,你就可以使用它:

CGFloat newRotation = 3.14f 

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.0]; // no tweening
CGAffineTransform transform = CGAffineTransformMakeRotation(newRotation);
self.transform = transform;
[UIView commitAnimations];

旋转应该确实发生在UIView的中心周围。 将animationDuration设置为零保证不会发生补间。

请确保您不会每秒执行60次此操作。使用这些工具创建类似动画的游戏非常诱人。这些类型的动画并不完全意味着基于帧到帧,“许多精灵飞来飞去”游戏。

为此 - 我一直走在那条路上 - 唯一的出路就是OpenGL。