0
votes

I'm animating UIImageView using iOS core animation "CABasicAnimation", all works fine for me but the only problem is when i animate to the position, after completeing animation it comes back to original position where it was. how can i overcome this? i need to keep UIImageView in moved position.

NOTE : I've seen few questions with success answers regarding this, but i have no idea why mine is not working like they say.

After rotating a CALayer using CABasicAnimation the layer jumps back to it's unrotated position

Here is my sample code,

    CGPoint endPt = CGPointMake(160, 53);
    CABasicAnimation *anim5 = [CABasicAnimation animationWithKeyPath:@"position"];
    [anim5 setBeginTime:CACurrentMediaTime()+0.4];
    anim5.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    anim5.fromValue = [NSValue valueWithCGPoint:imgRef.layer.position];
    anim5.toValue = [NSValue valueWithCGPoint:endPt];
    anim5.duration = 1.5;
    anim5.speed = 2;
    [imgRef.layer addAnimation:anim5 forKey:@"position"];

    //this is what other answers ask to do
    [anim5 setFillMode:kCAFillModeForwards];
    [anim5 setRemovedOnCompletion:NO];

BTW [imgRef.layer setPosition:CGPointMake(160, 53)]; won't help me since i'm delaying animation with 4 milliseconds.

2

2 Answers

3
votes

The root cause is that the animation just transitions the property between two values, it doesn't actually change the ending value. You need to change the ending value when the animation completes, there are three ways to do that. 1) Use the delegate property on the CAAnimation superclass to be notified of when the animation completes. At that point you can set the property to it's end value. See: https://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CAAnimation_class/Introduction/Introduction.html#//apple_ref/occ/cl/CAAnimation The animationDidStop:finished: is the method you'll need to implement on the delegate. 2) Set a completion block on the surrounding CATransaction. You'll need to manually start the CATransaction rather than having CABasicAnimation do that automatically for you. See: Objective-C - CABasicAnimation applying changes after animation? 3) See OMZ's comment below...

1
votes

The right answer is to set the layer's position property, but as you've pointed out, it makes it more difficult because you're wanting a 0.4 second delay prior to the position change. Is there any reason you couldn't perform the delay first and then do the animation? Something like this:

- (IBAction)didTapMove:(id)sender
{
  [self performSelector:@selector(animate) withObject:nil afterDelay:0.4];
}

- (void)animate
{
  CGPoint endPt = CGPointMake(160, 53);
  CABasicAnimation *anim5 = [CABasicAnimation animationWithKeyPath:@"position"];
  anim5.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  anim5.fromValue = [NSValue valueWithCGPoint:_imageView.layer.position];
  anim5.toValue = [NSValue valueWithCGPoint:endPt];
  anim5.duration = 1.5;
  anim5.speed = 2;

  [_imageView.layer addAnimation:anim5 forKey:@"position"];

  [_imageView.layer setPosition:CGPointMake(160, 53)];
}

Noticed I've removed your begin time from the animation since the delay is occurring in the perform selector call.