views:

91

answers:

2

I have a car image in a UIImageView, with movement and rotation animations. I have a tyre-mark image in a UIImageView, which i've added as a subview to the car. This means that all the same movement and rotation animations apply to both.

What I want to do is leave a trail of tyre skidmarks.

Can anyone suggest a strategy on how to do this?

Searching through other topics I saw this snippet, not sure if I can use it:

UIGraphicsBeginImageContext(drawingView.bounds.size);
[drawingView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//then display viewImage in another UIImageView...

If it were usable, any clue on how to get it called during an animation?

A: 

That snippet is not quite what you're looking for. That snippet saves what is currently displayed in the context as a UIImage. You can use the ImageContext to draw as well, but not like that.

Dan Lorenc
A: 

The ideal would be if CAKeyframeAnimation notified its delegate before doing the following keyframe; since I don't think that's possible (?) the only way I can think of doing something like this is using an array of positions, and using consecutive CABasicAnimation instances in order to do this. This is like a "poor man's" CAKeyframeAnimation.

Something like this:

- (void)viewDidLoad 
{
    [super viewDidLoad];

    _step = 0;
    _positions = [[NSArray alloc] initWithObjects:[NSValue valueWithCGPoint:CGPointMake(20.0, 20.0)],
                 [NSValue valueWithCGPoint:CGPointMake(40.0, 80.0)],
                 [NSValue valueWithCGPoint:CGPointMake(60.0, 120.0)],
                 [NSValue valueWithCGPoint:CGPointMake(80.0, 160.0)],
                 [NSValue valueWithCGPoint:CGPointMake(100.0, 200.0)],
                 [NSValue valueWithCGPoint:CGPointMake(120.0, 240.0)],
                 [NSValue valueWithCGPoint:CGPointMake(140.0, 280.0)],
                 [NSValue valueWithCGPoint:CGPointMake(160.0, 320.0)],
                 [NSValue valueWithCGPoint:CGPointMake(180.0, 360.0)],
                 [NSValue valueWithCGPoint:CGPointMake(200.0, 400.0)],
                 nil];
    [self moveToNextPosition];
}

- (void)moveToNextPosition
{
    if (_step < [_positions count] - 1)
    {
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
        animation.fromValue = [_positions objectAtIndex:_step];
        animation.toValue = [_positions objectAtIndex:(_step + 1)];
        animation.delegate = self;
        animation.removedOnCompletion = YES;
        [_sprite.layer addAnimation:animation forKey:@"position"];

        ++_step;
    }
    else 
    {
        _sprite.center = [[_positions objectAtIndex:_step] CGPointValue];
    }
}

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished
{
    UIImageView *trail = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"sprite.png"]];
    trail.center = [[_positions objectAtIndex:_step] CGPointValue];
    [self.view insertSubview:trail belowSubview:_sprite];
    [trail release];

    [self moveToNextPosition];
}

In this case, the animations execute one after the other, with values specified in the _positions NSArray ivar, and the _step is incremented at every step. When each animation stops, we draw a sprite image below the one we're animating, and we restart our animation, until there are no more points to move to. And then we finish.

Hope this helps!

Adrian Kosmaczewski