Почему CABasicAnimation отправит вид слоя назад и вперед? - PullRequest
2 голосов
/ 08 января 2011

Есть два UIViews одинакового размера.UIView one (A) изначально находится над UIView two (B).Когда я пытаюсь выполнить CABasicAnimation transform.rotation.y на слое А:

CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
CGFloat startValue = 0.0;
CGFloat endValue = M_PI;
rotateAnimation.fromValue = [NSNumber numberWithDouble:startValue];
rotateAnimation.toValue = [NSNumber numberWithDouble:endValue];
rotateAnimation.duration = 5.0;
[CATransaction begin];
[imageA.layer addAnimation:rotateAnimation forKey:@"rotate"];
[CATransaction commit];

Во время анимации UIView (A) слоя анимации будет:

  1. отправлено обратно (Aвнезапно отстает от B)
  2. вращается ... пройдена вторая половина анимации
  3. передан фронт (A теперь снова на вершине B)

Есть лиспособ держать A на вершине B в течение всего периода анимации?Спасибо!

ОБНОВЛЕНИЕ: источник проекта подключен: FlipLayer.zip

Ответы [ 3 ]

10 голосов
/ 11 января 2011

Проблема заключается в том, что вращение вокруг оси Y в настоящей 3D-системе композитинга заставит слой A пересекаться со слоем B, так что половина слоя A должна быть видимой, а половина должна быть позади слоя B. CoreAnimation не обеспечиваетнастоящая система 3D композитинга.Вместо этого он пытается определить, какой слой находится перед каким другим слоем, и отображает его полностью без пересечения.В вашем случае во время первой половины ротации CoreAnimation приняла решение, что слой B находится поверх слоя A в трехмерном пространстве.Самое простое решение, вероятно, состоит в том, чтобы установить zPosition слоя A на layer.bounds.size.width (по умолчанию 0) на время анимации (или постоянно, если оно всегда должно быть сверху).

Если вы хотитеустановите его только на время анимации, вы можете добавить вторую анимацию для ключевого пути transform.translation.z.Вот ваш -flip метод, модифицированный для использования этого:

- (IBAction)flip:(id)sender {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    CGFloat startValue = 0.0;
    CGFloat endValue = M_PI;
    animation.fromValue = [NSNumber numberWithDouble:startValue];
    animation.toValue = [NSNumber numberWithDouble:endValue];
    animation.duration = 5.0;
    [imageOne.layer addAnimation:animation forKey:@"rotate"];
    animation.keyPath = @"transform.translation.z";
    animation.fromValue = [NSNumber numberWithFloat:imageOne.layer.bounds.size.width];
    animation.toValue = animation.fromValue;
    [imageOne.layer addAnimation:animation forKey:@"zPosition"];
}
0 голосов
/ 11 января 2011

Вы можете попытаться перевести ось z и вывести A вперед.Выполните вращение, а затем установите z обратно в начальное значение.

Кроме того, вы, вероятно, не увидите перспективу вращения, если не установите свойство .m34 в преобразовании.Попробуйте что-то вроде этого:

CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0f / -300.0f;
transform = CATransform3DRotate(transform, 0.0f, M_PI, 0.0f);

CABasicAnimation *rotateAnimation = [CABasicAnimation 
                                          animationWithKeyPath:@"transform"];
rotateAnimation.fromValue = [NSValue 
                                 valueWithCATransform3D(CATransformIdentity)];
rotateAnimation.toValue = [NSValue valueWithCATransform3D(transform)];
rotateAnimation.duration = 5.0;

[imageA.layer addAnimation:rotateAnimation forKey:@"rotate"];

Ваш блок транзакций не нужен.

С наилучшими пожеланиями.

0 голосов
/ 11 января 2011

Вы пытались добавить [self.view bringSubviewToFront:imageA]; в последовательность анимации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...