CABasicAnimation的toValue是否相对于初始位置? [英] Is CABasicAnimation's toValue relative to initial position?
问题描述
我有一个 CALayer
,我明确地将其设置为一个新职位。我的 toValue
属性似乎仅相对于图层的初始位置。
I have a CALayer
that I'm explicitly animating to a new position. My toValue
property seems only relative to the layer's initial position.
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.center
的 float
值添加到图层的起始位置一样。
So this code isn't redrawing the layer to the view's center. It seems as if it's really redrawing the layer to CGPointMake(self.view.center.x + blueDot.position.x, self.view.center.y + blueDot.position.y)
, like it's adding the float
values of self.view.center
to the layer's starting position.
toValue
属性是否应该具有这种功能?将我的 blueDot
移动到视图中心的最干净的方法是什么?
Is the toValue
property supposed to act like this? What's the cleanest way to move my blueDot
to the center of the view?
编辑:
-(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.
推荐答案
问题是您要移动框架
,但是此 CAShapeLayer
的蓝点路径
已在该图层的框架
中由 self.view.center.x-60-5,163.5
偏移您在为 CAShapeLayer
创建路径
时指定。因此,当为图层的位置
设置动画时,蓝点仍将从该新的位置
偏移该数量。
The issue is that you're moving the frame
of the layer, but the blue dot path
of this CAShapeLayer
has been offset within that layer's frame
by self.view.center.x - 60 - 5, 163.5
, the coordinates you specified when creating the path
for that CAShapeLayer
. So when you animate the position
of the layer, the blue dot will still be offset by that amount from this new position
.
解决方法是定义 CAShapeLayer $ c $的
路径
c>位于图层的左上角,例如
The fix is to define the path
of the CAShapeLayer
to be in the upper left corner of the layer, e.g.
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;
现在,当您移动位置
时,
顺便说一句,我通常会创建一个单独的 UIView
并将此 CAShapeLayer
添加到其中。这样,您可以享受各种不同的功能:
As an aside, I'd generally create a separate UIView
and add this CAShapeLayer
to that. This way, you can enjoy a variety of different features:
- 您可以享受
UIView
基于块的动画; - 您可以使用
center
移动它,以便在移动其center $ c $时c>到其父视图的
中心
,它实际上将居中(现在,如果将位置
self.view.center
的图层,它并不是真的居中,因为它将是位于中心的蓝点图层的左上角); - 您可以使用UIKit Dynamics将其捕捉到位置或定义其他行为,
- 您可以使用自动布局约束来指定放置位置
- ,您可以定义
UIView
子类,该子类是IBDesignable
并带有该点作为视图,以便您可以将其添加到情节提要上并查看其外观;等等。
- you can enjoy
UIView
block-based animation; - you can use
center
to move it around so that when you move itscenter
to thecenter
of its superview, it will really be centered (right now, if you move theposition
of the layer toself.view.center
, it's not really quite centered, as it will be the upper left corner of the blue dot's layer that will be in the center); - you can use UIKit Dynamics to snap it to location or define other behaviors,
- you can use auto-layout constraints to dictate placement if you want,
- you could define a
UIView
subclass that isIBDesignable
with this dot as a view so that you could add it on a storyboard and see what it looks like; etc.
这篇关于CABasicAnimation的toValue是否相对于初始位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!