CGRect не меняется во время анимации

Я анимирую UIView и хочу проверить, пересекается ли его фрейм с фреймом другого UIView. Вот как я «порождаю» один из 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];
}

Все идет нормально. Теперь я хочу проверить, не конфликтуют ли этот UIView и другой мой UIView, выполнив следующие действия:

- (void) checkCollision {

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

}

Однако они никогда не сталкиваются. Хотя я вижу, как oncomer1 перемещается по экрану, loggin oncomer1.frame никогда не меняется: он продолжает выводить Oncomer: {{50, 520}, {30, 60}} (которые являются значениями после анимации).

Кто-нибудь знает, почему это так?

P.S. Оба метода вызываются прямо или косвенно с помощью NSTimer и, таким образом, выполняются в фоновом режиме.


person Thomas K    schedule 13.08.2011    source источник
comment
Что делает NSLog(@Oncomer: %@, NSStringFromCGRect(oncomer1.frame)); вывод после завершения анимации?   -  person msgambel    schedule 13.08.2011
comment
Это значение. Я понял, что это значение после анимации. oncomer1.frame устанавливается на это значение, как только начинается анимация.   -  person Thomas K    schedule 13.08.2011
comment
Я думаю, что было бы неплохо смотреть в центр представления, а не на кадр во время анимации. Почему бы не попробовать сделать прямоугольник на основе центральной точки в вашем методе checkCollision, чтобы проверить, работает ли это? Однако сначала попробуйте NSLogging центральную точку, чтобы увидеть, изменяется ли она во время анимации.   -  person msgambel    schedule 13.08.2011
comment
На самом деле, просто попробуйте заменить .frame на .bounds и посмотрите, сработает ли это.   -  person msgambel    schedule 13.08.2011
comment
Не работает. границы oncomer1 всегда: {0, 0}   -  person Thomas K    schedule 14.08.2011


Ответы (2)


UIView обновления геометрии немедленно применяются к их CALayer, даже в блоке анимации. Чтобы получить версию слоя с примененной анимацией, вы можете использовать -[CALayer presentationLayer], например так (предупреждение - непроверенный код):

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

}
person ianh    schedule 13.08.2011

Из вашего кода:

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

Логическое объяснение того, что фрейм никогда не меняется, заключается в том, что вы меняете только y фрейма и всегда устанавливаете его на одно и то же значение, определяемое двумя height.

person Mundi    schedule 13.08.2011