CATransaction: изменения слоя, но не анимируют

Я пытаюсь анимировать часть UI в приложении для iPad, когда пользователь касается кнопки. У меня есть этот код в моем методе действия. Это работает в том смысле, что UI изменяется, как я ожидаю, но это не анимирует изменения. Это просто сразу изменяется. Я должен пропускать что-то:

- (IBAction)someAction:(id)sender {
    UIViewController *aViewController = <# Get an existing UIViewController  #>;
    UIView *viewToAnimate = aViewController.view;
    CALayer *layerToAnimate = viewToAnimate.layer;

    [CATransaction begin];
    [CATransaction setAnimationDuration:1.0f];

    CATransform3D rotateTransform = CATransform3DMakeRotation(0.3, 0, 0, 1);
    CATransform3D scaleTransform = CATransform3DMakeScale(0.10, 0.10, 0.10);
    CATransform3D positionTransform = CATransform3DMakeTranslation(24, 423, 0);
    CATransform3D combinedTransform = CATransform3DConcat(rotateTransform, scaleTransform);
    combinedTransform = CATransform3DConcat(combinedTransform, positionTransform);
    layerToAnimate.transform = combinedTransform;

    [CATransaction commit];

    // rest of method...
}

Я попытался упростить анимацию, чтобы просто изменить непрозрачность (например), и она все еще не анимирует. Непрозрачность просто изменяется немедленно. Это приводит меня полагать, что что-то не установка правильно.

Любые подсказки были бы полезны!

13
задан macinjosh 5 June 2010 в 19:11
поделиться

2 ответа

Анимация на корневом слое представления по умолчанию отключена. Попробуйте применить преобразование к представлению, например [view setTransform:CGTransform3D...]. Если вы должны делать это на уровне слоев, добавьте слой к корневому слою и выполняйте преобразования на нем. Также блок анимации вида [UIView beginAnimations...] действует только при анимации свойств вида - в отличие от свойств слоя.

Обновление:

Итак, вот как будет выглядеть ваш код с явной анимацией (CATransaction не требуется)

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D rotateTransform = CATransform3DMakeRotation(0.3, 0, 0, 1);
CATransform3D scaleTransform = CATransform3DMakeScale(0.10, 0.10, 0.10);
CATransform3D positionTransform = CATransform3DMakeTranslation(24, 423, 0);
CATransform3D combinedTransform = CATransform3DConcat(rotateTransform, scaleTransform);
combinedTransform = CATransform3DConcat(combinedTransform, positionTransform);
[anim setFromValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]];
[anim setToValue:[NSValue valueWithCATransform3D:combinedTransform]];
[anim setDuration:1.0f];

[layerToAnimate addAnimation:anim forKey:nil];

Помните, что это только выполняет анимацию. На самом деле вы должны установить свойство transform слоя с помощью вызова:

[layerToAnimate setTransform:combinedTransform];

также. В противном случае он просто вернется в исходное положение.

Свойства слоя анимируются неявно, когда вы их задаете за исключением случая, когда вы анимируете корневой слой представления. В этом случае анимация отключена по умолчанию, и я обнаружил, что мне всегда приходится анимировать представление, а не слой, когда я заинтересован в анимации корневого слоя. Итак, это означает, что вызов любого слоя в дереве слоев, который изменяет свойство, будет анимирован неявно. Например:

CALayer *root = [view layer];

CALayer *sublayer = [[root sublayers] objectAtIndex:0];

[sublayer setTransform:combinedTransform];

Это единственный способ, который я знаю (знал), как можно использовать неявную анимацию на слое. Однако ваш код указывает на то, что вы можете включить анимацию слоя для корневого слоя, просто поместив изменения слоя в блок анимации UIView. Это довольно интересно и удобно. Это довольно полезное открытие.

Возможно, это зарыто где-то в документации, но я еще не сталкивался с этим.

30
ответ дан 1 December 2019 в 19:30
поделиться

Оказывается, вы можете включить анимацию слоя для корневого слоя, установив для его свойства делегата значение nil. Не знаю, хорошая ли это практика.

2
ответ дан 1 December 2019 в 19:30
поделиться