Rotating CAShapeLayer moves the position too

旧时模样 提交于 2019-12-01 03:11:09

tl;dr: your shape layer is missing a frame (probably the bounding box of its path).


The confusion comes from the fact that the layer being rotated has no frame. This means that its size is 0⨉0. This combined with the fact that the shape layer allows the shape to be drawn outside of its bounds makes it look like the rotation is happening around an exterior point. But it's not.

The problem

Without any modification to the anchor point, the transform is happening relative to the center of the layer's own bounds. For a layer with no size, the center is the same as the origin ((x+width/2, y+height/2) is the same as (x, y) when both width and height are 0).

The local origin (relative to the layer's bounds) is also where the path is drawn relative to. The point (0, 0) for the path is in the origin of the shape layer.

If we were to display the center (and in this case the origin) of the layer, this is what it would look like.

This is also the point that the shape is rotated around.

Solving it...

The are essentially two ways of solving this problem, making it rotate around the center of the circle. One is to alter the path so that the circles center is at (0,0), the origin. Another solution, which I generally prefer, is to give the layer a size that matches the size of its path, the paths bounding box:

circleLayer.bounds = CGPathGetBoundingBox(circle.CGPath);

Here I'm showing the layer with a very light gray background color:

I sometimes find it useful to give a shape layer a background color during development as a debugging tool so that I can see that its frame matches my expectations.

Note that when you change the bounds of a layer or view, it resizes relative to its position. This means that the center point stays the same and the origin moves, meaning that the path will effectively move.

Now that the layer has a size, and the center of the bounds matches the center of the circle, it will look like the circle is rotating around it's center when you rotate the shape layer.

When you see that everything is working, you can remove the background color again.

It works right. Just enable frame for your layer:

circleLayer.borderWidth = 1;
circleLayer.borderColor = [UIColor redColor].CGColor;

And you see that frame rotating right. Also better to use byValue here:

CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.byValue = @(2 * M_PI);
animation.duration = 10.0f;
animation.repeatCount = INFINITY;
animation.removedOnCompletion = NO;
[circleLayer addAnimation:animation forKey:@"SpinAnimation"];

So your problem is a geometry of shape.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!