我正在创建一个CAShapeLayer。我正在为它添加旋转动画。不知何故转化结果很奇怪。子图层随着旋转一起移动。我需要它在固定的中心/位置(锚)并旋转。我知道它弄乱了几何变换,但我无法做到正确。
我尝试过设置anchorpoint。我也遵循了这个post
以下是代码:
UIBezierPath *circle = [UIBezierPath bezierPathWithArcCenter:CGPointMake(75, 125)
radius:50
startAngle:0
endAngle:1.8 * M_PI
clockwise:YES];
CAShapeLayer *circleLayer = [CAShapeLayer layer];
[circleLayer setFrame:CGRectMake(200 - 50, 300 - 50, 100, 100)];
circleLayer.path = circle.CGPath;
circleLayer.strokeColor = [UIColor orangeColor].CGColor;
[circleLayer setFillColor:[UIColor clearColor].CGColor];
circleLayer.lineWidth = 3.0;
if ([circleLayer animationForKey:@"SpinAnimation"] == nil) {
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat: 2 * M_PI];
animation.duration = 10.0f;
animation.repeatCount = INFINITY;
animation.removedOnCompletion = NO;
[circleLayer addAnimation:animation forKey:@"SpinAnimation"];
}
[self.view.layer addSublayer:circleLayer];
答案 0 :(得分:28)
tl; dr:您的形状图层缺少一个框架(可能是其路径的边界框)。
混淆来自于被旋转的层没有框架的事实。这意味着它的大小为0⨉0。这与形状层允许将形状绘制在其边界之外的事实相结合,使得它看起来像是在外部点周围发生旋转。但事实并非如此。
在没有对锚点进行任何修改的情况下,转换相对于图层自身边界的中心发生。对于没有大小的图层,中心与原点相同(当(x+width/2, y+height/2)
和(x, y)
为width
时,height
与0
相同
本地原点(相对于图层的边界)也是相对于路径绘制的位置。路径的点(0, 0)
位于形状图层的原点。
如果我们要显示图层的中心(在本例中是原点),这就是它的样子。
这也是形状旋转的重点。
基本上有两种方法可以解决这个问题,使其围绕圆心旋转。一种是改变路径,使得圆心位于(0,0),即原点。我通常更喜欢的另一个解决方案是给图层一个与其路径大小匹配的大小,即路径边界框:
circleLayer.bounds = CGPathGetBoundingBox(circle.CGPath);
这里我显示的图层具有非常浅灰色的背景色:
我有时会发现在开发过程中将形状图层作为调试工具赋予形状图层很有用,这样我就可以看到它的框架符合我的期望。
请注意,更改图层或视图的边界时,它会相对于其位置调整大小。这意味着中心点保持不变并且原点移动,这意味着路径将有效移动。
现在图层有一个大小,并且边界的中心与圆的中心相匹配,当你旋转形状图层时,它看起来就像圆圈围绕它旋转一样。
当您看到一切正常时,您可以再次删除背景颜色。
答案 1 :(得分:1)
它运作正常。只需为您的图层启用框架:
circleLayer.borderWidth = 1;
circleLayer.borderColor = [UIColor redColor].CGColor;
你看到那个框架向右旋转。在这里使用byValue
也更好:
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"];
所以你的问题是形状的几何形状。