【问题标题】:Rotating CAShapeLayer moves the position too旋转 CAShapeLayer 也会移动位置
【发布时间】:2015-10-14 22:48:53
【问题描述】:

我正在创建一个 CAShapeLayer。我正在向它添加旋转动画。不知何故,转换结果很奇怪。子层随着旋转而移动。我需要它处于固定的中心/位置(锚)并旋转。我知道它搞砸了几何变换,但我无法正确处理。

我试过设置锚点。我也关注了这个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];

【问题讨论】:

    标签: objective-c calayer caanimation


    【解决方案1】:

    tl;dr:您的形状图层缺少一个框架(可能是其路径的边界框)。


    混淆来自于被旋转的图层没有框架。这意味着它的大小是 0⨉0。这与形状层允许在其边界之外绘制形状的事实相结合,使得旋转看起来像是围绕外部点发生的。但事实并非如此。

    问题

    在不对锚点进行任何修改的情况下,变换是相对于图层自身边界的中心进行的。对于没有大小的层,中心与原点相同(当widthheight 都是0 时,(x+width/2, y+height/2)(x, y) 相同)。

    本地原点(相对于图层边界)也是绘制路径的相对位置。路径的点(0, 0) 位于形状层的原点。

    如果我们要显示图层的中心(在本例中是原点),这就是它的样子。

    这也是形状旋转的点。

    正在解决它...

    解决这个问题基本上有两种方法,让它围绕圆心旋转。一种是改变路径,使圆心位于原点 (0,0)。我通常更喜欢的另一种解决方案是为层提供与其路径大小相匹配的大小,即路径边界框:

    circleLayer.bounds = CGPathGetBoundingBox(circle.CGPath);
    

    这里我用非常浅的灰色背景颜色显示图层:

    我有时发现在开发过程中为形状图层提供背景颜色作为调试工具很有用,这样我就可以看到它的框架符合我的期望。

    请注意,当您更改层或视图的边界时,它会相对于其位置调整大小。这意味着中心点保持不变并且原点移动,这意味着路径将有效移动。

    现在图层有了大小,并且边界的中心与圆的中心匹配,当您旋转形状图层时,看起来圆正在围绕它的中心旋转。

    当您看到一切正常时,您可以再次移除背景颜色。

    【讨论】:

    • 大卫,非常感谢。简而言之,不要忘记设置 CAShapeLayer 的界限 - 即,不要像我一样 :) 感谢上帝的精彩帖子。
    • 对我来说,框架没有设置为我的图层。所以 circleLayer.frame = CGPathGetBoundingBox(circle.CGPath); 解决了我的问题。
    • 谢谢大家,简而言之,不要忘记设置 CAShapeLayer 的 边界框架!!!
    • @Eddie boundsframe 属性是相互关联的,因此您只需设置其中一个即可为形状图层指定大小。
    • @DavidRönnqvist 我刚刚遇到过类似的问题,尝试只设置边界,然后只设置框架,两者都不起作用。然后,将它们都设置好,它就可以工作了。这个我不能说太多¯_(ツ)_/¯
    【解决方案2】:

    它工作正常。只需为您的图层启用框架:

    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"];
    

    所以你的问题是几何形状。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多