Possible Duplicate:
Rotate CGPath without changing its position
我搜索并测试了各种代码几个小时,但无法正常工作。
我在CAShapeLayer的随机位置处添加了任意UIBezierPath,该对象已添加到视图中。我需要旋转路径,以便可以处理设备旋转。我可以旋转图层而不是路径。我只需要旋转结果。
我已经有了通过缩放和转换来处理贝塞尔曲线路径的方法。效果很好,但是现在我只需要向左或向右旋转90度即可。
有关如何执行此操作的任何建议?
基本代码:UIBezierPath *path = <create arbitrary path> CAShapeLayer *layer = [CAShapeLayer layer]; [self addPathToLayer:layer fromPath:path]; // I could get the center of the box but where is the box center for the view it is in? // CGRect box = CGPathGetPathBoundingBox(path.CGPath); // layer.anchorPoint = ? How to find the center of the box for the anchor point? // Rotating here appears to rotate around 0,0 of the view layer.transform = CATransform3DMakeRotation(DegreesToRadians(-90), 0.0, 0.0, 1.0);
我看到以下帖子:
BezierPath Rotation in a UIView
我想我可以原样旋转,然后将路径平移回原位。我只需要弄清楚转换值是什么。
我还应该指出,尝试旋转后看到的是图像移出屏幕的某个位置。我尝试旋转25度以查看运动,它绕视图的原点0,0旋转,因此,如果我旋转90度,则图像不在屏幕上。我正在运行这些测试而无需旋转设备-只是为了看看旋转是如何工作的。
更新#1-2012年12月4日:出于某些奇怪的原因,如果我将位置设置为我凭经验发现的值,则旋转后将旋转的贝塞尔曲线路径移动到正确的位置:layer.position = CGPointMake(280, 60);
该值是从启动/停止应用程序和进行调整中得出的猜测。我不知道为什么我需要调整旋转位置。锚点应位于图层的中心。但是,我确实发现,即使设置了路径,CAShapeLayer的框架和位置也都为零,并且事实是该路径在视图内的正确位置。当旋转+90时,位置280、60会将路径移动到路径边界框的中心。如果更改旋转值,则需要调整位置。我不必手动进行此调整。
我认为最后的解决方法是将贝塞尔曲线路径转换为图像,然后将其添加。我发现,如果将图层内容设置为图像,然后旋转,则它将绕其中心点旋转,而无需进行位置调整。设置路径并非如此。
更新#2 2012年12月4日-我尝试设置框架,并通过摆弄使它居中,如下所示:CGRect box = CGPathGetPathBoundingBox(path.CGPath); CGRect rect = CGRectMake(0, 0, box.origin.x + (3.5 * box.size.width), box.origin.y + (3.5 * box.size.height)); layer.frame = rect; layer.transform = CATransform3DMakeRotation(DegreesToRadians(90), 0.0, 0.0, 1.0);
为什么要乘以3.5?我没有线索。我发现,将框的原点添加到框的大小的3.5倍左右,会将旋转的CAShapeLayer路径移动到应位于的位置。
必须有更好的方法来做到这一点。这是比我以前的文章更好的解决方案,因为框架大小不取决于旋转角度。我只是不知道为什么需要将框架设置为我要设置的值。我认为应该是
CGRectMake(0,0,box.origin.x +(box.size.width / 2),box.origin.y +(box.size.height / 2));
但是,它会使图像向左移动太多。
我发现的另一个线索是,如果我设置[self view] .frame的框架(整个父视图的框架,即iPhone的屏幕),然后旋转,则旋转点是屏幕的中心,该中心点周围的路径/图像轨道。这就是为什么我尝试将框架移动到路径的中心应位于框中心附近的原因。
更新#3 2012年12月4日-我尝试将图层渲染为图像。但是,似乎只设置图层的路径并不能使它成为图层中的“图像”,因为它是空的CGRect box = CGPathGetPathBoundingBox(path.CGPath); layer.frame = box; UIImage *image = [ImageHelper imageFromLayer:layer]; // ImageHelper library I created CAShapeLayer *newLayer = [CAShapeLayer layer]; newLayer.frame = CGRectMake(box.origin.x, box.origin.y, image.size.width, image.size.height); newLayer.contents = (id) image.CGImage;
看起来,旋转设置了路径的图层与简单旋转贝塞尔曲线路径本身没有什么不同。我将回到旋转贝塞尔曲线的路径,看看我是否可以摆弄位置元素或其他东西。必须有一个解决方案。
目标:在最初创建的视图内围绕其中心点旋转UIBezierPath。
更新#4 2012年12月4日-我进行了一系列测试,测量了转换所需的值,以便将UIBezierPath放置在其先前的中心位置。CGAffineTransform rotate = CGAffineTransformMakeRotation(DegreesToRadians(-15)); [path applyTransform:rotate]; // CGAffineTransform translate = CGAffineTransformMakeTranslation(-110, 70); // -45 CGAffineTransform translate = CGAffineTransformMakeTranslation(-52, -58); // -15 [path applyTransform:translate];
但是,x / y平移的比率不对应,因此我无法根据角度推断所需的平移。似乎“CGAffineTransformMakeRotation”使用放置了一些任意锚点进行旋转,此刻似乎是(viewWidth / 2,0)。我正在使这比需要做的难得多。我缺少进行简单的旋转以便保持中心点的功能。我只需要向左或向右90度“旋转”路径。
更新#5 12/4/2012-运行其他测试后,似乎旋转UIBezierPath的锚点是绘制所有点的原点。在这种情况下,原点为0,0,所有点均相对于该点。因此,应用旋转,旋转围绕原点发生,这就是为什么路径在-90上右移,在90上左移的原因。我需要以某种方式将旋转的锚点设置为中心它围绕中心而不是原始原点“旋转”。在此问题上花费了12个小时。