Make CABasicAnimation for iOS Running Multiple Times

323 Views Asked by At

I'm building an app that will have an animation of one image "walking" across the screen, using simple CABasicAnimation. I have it set for it to walk a certain distance in a duration, and then stop until the user gives it more commands, in which it will continue walking for the same distance and duration again. The issue that I have is that after the first time, the image will stop where it should, but it won't continue to walk, it will jump back to its original spot and start over. I thought I had this set correctly on the origin point, but I guess not.

CABasicAnimation *hover = [CABasicAnimation animationWithKeyPath:@"position"];
    hover.fillMode = kCAFillModeForwards;
    hover.removedOnCompletion = NO;
    hover.additive = YES; // fromValue and toValue will be relative instead of absolute values
    hover.fromValue = [NSValue valueWithCGPoint:CGPointZero];
    hover.toValue = [NSValue valueWithCGPoint:CGPointMake(110.0, -50.0)]; // y increases downwards on iOS
    hover.autoreverses = FALSE; // Animate back to normal afterwards
    hover.duration = 10.0; // The duration for one part of the animation (0.2 up and 0.2 down)
    hover.repeatCount = 0; // The number of times the animation should repeat
    [theDude.layer addAnimation:hover forKey:@"myHoverAnimation"];
1

There are 1 best solutions below

4
On BEST ANSWER

Your from value is set to be zero and it's not being updated.

hover.fromValue = [NSValue valueWithCGPoint:CGPointZero];

You have to update this value with your to value each time.

Here I've put your code in a function where you can update starting and ending points.

- (void)moveFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint {
    CABasicAnimation *hover = [CABasicAnimation animationWithKeyPath:@"position"];
    hover.fillMode = kCAFillModeForwards;
    hover.removedOnCompletion = NO;
    hover.additive = YES; // fromValue and toValue will be relative instead of absolute values
    hover.fromValue = [NSValue valueWithCGPoint:fromPoint];
    hover.toValue = [NSValue valueWithCGPoint:toPoint]; // y increases downwards on iOS
    hover.autoreverses = FALSE; // Animate back to normal afterwards
    hover.duration = 10.0; // The duration for one part of the animation (0.2 up and 0.2 down)
    hover.repeatCount = 0; // The number of times the animation should repeat
    [theDude.layer addAnimation:hover forKey:@"myHoverAnimation"];
}

You can move the guy further by calling this function with new points each time.

[self moveFromPoint:CGPointZero toPoint:CGPointMake(110.0, -50.0)]

[self moveFromPoint:CGPointMake(110.0, -50.0) toPoint:CGPointMake(160.0, -50.0)]

EDIT:

I see that you want to move the guy with the same ratio but in different lenght each time.

Add this variable just after the @interface:

@property (nonatomic) CGPoint oldPointOfTheGuy;

And add this new function just after the previous function:

- (void)moveByDistance:(CGFloat)distance {
    CGPoint newPointOfTheGuy = CGPointMake(self.oldPointOfTheGuy.x + 2.2*distance, self.oldPointOfTheGuy.y + distance);
    [self moveFromPoint:self.oldPointOfTheGuy toPoint:newPointOfTheGuy];
    self.oldPointOfTheGuy = newPointOfTheGuy;
}

And set a starting point for the guy in your viewDidLoad:

self.oldPointOfTheGuy = CGPointMake(110.0, -50)

Now we have set the old position of the guy as where we know he spawns for the first time.

From now on, each time we want to move him, we will call this:

[self moveByDistance:20];

What this function does is, since that it already knows your x / y ratio which is 2.2, it just adds 20 to your old y position and adds 2.2 * 20 to your old x position. And each time a new position is set, old position is updated.

Hope this helps.