使用核心动画在屏幕上移动UIImage

Tan*_*ner 1 cocoa-touch core-animation caanimation ios

不要发布关于我喜欢的动画的答案我理解UIView,我正在学习核心动画.我试图让图像向右移动50个单位,但我遇到了很多问题.首先,当调用动画时,图像跳转到新位置,运行,然后跳回原始位置.我希望它只是向右移动50个单位,如果按下按钮则停止,再次移动.我花了很多时间研究,似乎无法找到问题.我的代码:

-(IBAction)preform:(id)sender{

CGPoint point = CGPointMake(imView.frame.origin.x, imView.frame.origin.y);
imView.layer.position = point;

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
anim.fromValue  = [NSValue valueWithCGPoint:point];
anim.toValue    = [NSValue valueWithCGPoint:CGPointMake(point.x + 50, point.y)];
anim.duration   = 1.5f;
anim.repeatCount =1;
anim.removedOnCompletion = YES;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
[imView.layer  addAnimation:anim forKey:@"position.x"];
imView.layer.position = point;

}
Run Code Online (Sandbox Code Playgroud)

rob*_*off 16

我在你的代码中看到了几个问题.

首先,你像这样抓住框架原点:

CGPoint point = CGPointMake(imView.frame.origin.x, imView.frame.origin.y);
Run Code Online (Sandbox Code Playgroud)

虽然这不是一个真正的问题,但你可以这样做:

CGPoint point = imView.frame.origin;
Run Code Online (Sandbox Code Playgroud)

问题是你要将图层设置position为其框架的原点.但默认情况下,位置控制视图的中心,框架的原点是左上角.您可能想要首先获取图层的位置:

CGPoint point = imView.layer.position; // equivalent to imView.center
Run Code Online (Sandbox Code Playgroud)

其次,您正在使用position.x需要CGFloat值的键路径,但您提供的是CGPoint值.这似乎不会导致iOS 6.1模拟器出现问题,但假设它始终有效可能是一个坏主意.

第三,你要明白,一个动画并不会改变你的层的属性!您通常操作的每个图层(技术上称为模型图层)都有一个关联的表示层.表示层的属性控制屏幕上的内容.当您更改模型图层的属性时,Core Animation通常会自动在表示层上设置动画(从旧值到新值).这称为隐式动画.A UIView抑制其图层上的隐式动画.

当表示层上的动画结束并被删除时,表示层的属性将恢复为其模型层的值.因此,要使更改成为永久更改,您需要更新模型图层的属性.一般来说,最好更新模型层的属性首先,然后添加动画,让您的明确动画覆盖隐含动画(如果已创建).

碰巧的是,虽然你可以设置动画position.x,但你需要positionmodel图层上设置它以使其坚持下去.我测试了这个工作:

- (IBAction)perform:(id)sender {
    CGPoint point0 = imView.layer.position;
    CGPoint point1 = { point0.x + 50, point0.y };

    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"position.x"];
    anim.fromValue    = @(point0.x);
    anim.toValue  = @(point1.x);
    anim.duration   = 1.5f;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

    // First we update the model layer's property.
    imView.layer.position = point1;

    // Now we attach the animation.
    [imView.layer  addAnimation:anim forKey:@"position.x"];
}
Run Code Online (Sandbox Code Playgroud)

(注意我调用了我的方法perform:.原帖中的方法似乎拼错了.)

如果您想真正了解Core Animation,我强烈建议您观看WWDC 2011中的Core Animation Essentials视频.它只需一小时,并且包含大量有用的信息.