CATransaction: слой изменяется, но не анимируется - PullRequest
13 голосов
/ 05 июня 2010

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

- (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...
}

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

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

Ответы [ 3 ]

30 голосов
/ 06 июня 2010

Анимации в корневом слое вида по умолчанию отключены. Попробуйте вместо этого применить преобразование к представлению, например, [посмотреть 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];

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

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

3 голосов
/ 16 сентября 2010

Настройка вашего layerToAnimate делегата на ваш rootView.layer работает:

viewToAnimate.layer.delegate = rootView.layer;

Предполагается, что вы добавляете вид / слой в корневой вид / слой. Не удается найти, где это изменилось, неявные анимации используются только для работы.

2 голосов
/ 05 августа 2010

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

...