Question

I'm animating an UIView and want to check if its frame intersects with another UIView's frame. This is how I "spawn" one of the UIViews:

- (void) spawnOncomer 
{    
oncomer1 = [[Oncomer alloc] initWithType:@"car"];
    [self.view addSubview:oncomer1];


    //make the oncomer race across the screen
    [UIView beginAnimations:nil context:NULL]; {
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationDuration:3.0];
        [UIView setAnimationDelegate:self];
        CGRect f = oncomer1.frame;
        f.origin.y = self.view.frame.size.height+oncomer1.frame.size.height;
        oncomer1.frame = f;
        [UIView setAnimationDidStopSelector:@selector(decountCar)];
    } 
    [UIView commitAnimations];
}

So far so good. Now I want to check if this UIView and my other UIView collide by doing this:

- (void) checkCollision {

    bool collision = CGRectIntersectsRect(car.frame, oncomer1.frame);
    if (collision) {
        NSLog(@"BOOOOOOOM");
    } else {
        NSLog(@"Oncomer: %@", NSStringFromCGRect(oncomer1.frame));
    }

}

However, they never collide. Although I see oncomer1 moving across the screen, loggin oncomer1.frame never changes: it keeps outputting Oncomer: {{50, 520}, {30, 60}}(which are the post-animation values).

Does anyone know why this is?

P.s. Both methods are called directly or indirectly with a NSTimer and are thus performed in the background

Was it helpful?

Solution

UIView geometry updates apply immediately to their CALayer, even in an animation block. To get a version of a layer with animations applied, you can use -[CALayer presentationLayer], like this (warning - untested code):

- (void) checkCollision {
    CGRect oncomerFrame = oncomer1.layer.presentationLayer.frame;
    bool collision = CGRectIntersectsRect(car.frame, oncomerFrame);
    if (collision) {
        NSLog(@"BOOOOOOOM");
    } else {
        NSLog(@"Oncomer: %@", NSStringFromCGRect(oncomerFrame));
    }

}

OTHER TIPS

From your code:

CGRect f = oncomer1.frame;
f.origin.y = self.view.frame.size.height+oncomer1.frame.size.height;
oncomer1.frame = f;

A logical explanation of the frame never changing is that you are only changing the y of the frame, and you are always setting it to the same value determined by two heights.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top