相对于初始位置,CABasicAnimation的值是否为?

我有一个CALayer ,我明确地动画到一个新的位置。 我的toValue属性似乎只相对于图层的初始位置。

  CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:@"position"]; move.fromValue = [NSValue valueWithCGPoint:CGPointMake(blueDot.position.x, blueDot.position.y)]; move.toValue = [NSValue valueWithCGPoint:CGPointMake(self.view.center.x, self.view.center.y)]; move.duration = 1.0; [blueDot addAnimation:move forKey:@"myMoveAnimation"]; blueDot.position = CGPointMake(self.view.center.x, self.view.center.y); 

因此,此代码不会将图层重新绘制到视图的中心。 似乎它真的将图层重绘为CGPointMake(self.view.center.x + blueDot.position.x, self.view.center.y + blueDot.position.y) ,就像它添加了self.view.centerfloat值一样self.view.center到图层的起始位置。

toValue属性应该像这样吗? 将blueDot移动到视图中心的最blueDot方法是什么?


编辑:

  -(void)viewDidLoad { [super viewDidLoad]; blueDot = [CAShapeLayer layer]; [blueDot setPath:[[UIBezierPath bezierPathWithOvalInRect:CGRectMake(self.view.center.x - 60 - 5, 163.5, 10, 10)] CGPath]]; [blueDot setStrokeColor: [UIColor blueColor]CGColor]; [blueDot setFillColor:[UIColor blueColor]CGColor]; [[self.view layer] addSublayer:blueDot]; } // 163.5 is a placeholder for another view's position value so it's more readable for you guys. 

问题是你正在移动图层的frame ,但是这个CAShapeLayer的蓝点path已经在CAShapeLayer self.view.center.x - 60 - 5, 163.5 CAShapeLayer在该图层的frame内偏移,这是您在创建时指定的坐标CAShapeLayerpath 。 因此,当您为图层的position设置动画时,蓝点仍将从此新position偏移该量。

修复是将CAShapeLayerpath定义在图层的左上角,例如

 CAShapeLayer *blueDot = [CAShapeLayer layer]; blueDot.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(5, 5) radius:5 startAngle:0 endAngle:M_PI * 2 clockwise:true].CGPath; // note that using arc often generates a better looking circle, probably not noticeable at this size, just probably good practice blueDot.fillColor = [UIColor blueColor].CGColor; 

现在当你移动position ,这就是蓝点原点移动的位置。


CAShapeLayerCAShapeLayer ,我通常会创建一个单独的UIView并将此CAShapeLayer添加到其中。 这样,您就可以享受各种不同的function:

  • 你可以享受UIView基于块的动画;
  • 你可以使用center来移动它,这样当你将它的center移动到它的超视图的center时,它将真正居中(现在,如果你将图层的position移动到self.view.center ,它不是真的很居中,因为它将位于蓝点的左上角,将位于中心);
  • 您可以使用UIKit Dynamics将其捕捉到位置或定义其他行为,
  • 如果需要,您可以使用自动布局约束来指定展示位置,
  • 您可以使用此点作为视图定义一个IBDesignableUIView子类,以便您可以将它添加到故事板上并查看它的外观; 等等

您可以在视图的超view的坐标系中设置toValue(因为使用了center属性)。 看起来这应该工作:

 CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:@"position"]; move.fromValue = [NSValue valueWithCGPoint:CGPointMake(blueDot.position.x, blueDot.position.y)]; move.toValue = [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds))]; move.duration = 1.0; [blueDot addAnimation:move forKey:@"myMoveAnimation"]; blueDot.position = CGPointMake(CGRectGetMidX(view.bounds), CGRectGetMidY(view.bounds));