Анимируйте настраиваемые свойства CALayer внутри CATransaction

До сих пор я мог анимировать пользовательские свойства моего подкласса CALayer благодаря + (BOOL)needsDisplayForKey:(NSString *)key и CABasicAnimations.

Однако оказывается, что объединение анимаций в цепочку может стать очень сложным, потому что весь код выполняется в одном animationDidStop:finished: методе.

Поэтому я хотел переключиться на CATransactions, поскольку они поддерживают новый синтаксис блока, который позволил бы мне указать блок завершения с помощью + (void)setCompletionBlock:(void (^)(void))block.

Но мне кажется, что CATransaction может анимировать только так называемые «анимируемые свойства», и это не работает с моими настраиваемыми свойствами слоя, даже с реализованным методом needsDisplayForKey:.

Так есть ли способ сделать настраиваемые свойства в CALayer для анимации с CATransaction?

РЕДАКТИРОВАТЬ: Я намерен сделать что-то вроде:

[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
    NSLog(@"blabla");
}];

myLayer.myProperty = newValue;

[CATransaction commit];

Обновление значения myProperty до newValue не анимировано. Я попытался реализовать actionForLayer:forKey: в представлении, управляющем myLayer, чтобы вернуть CABasicAnimation. Но actionForLayer:forKey: никогда не вызывается с ключом myProperty. И да, myLayer не view.layer, а подслой, и да, я установил делегата myLayer на содержащее представление.


person romrom    schedule 08.11.2010    source источник


Ответы (2)


Я считаю, что, читая некоторый исходный код, вы все еще можете использовать CABasicAnimation в CATransaction. Любой CAAnimations, добавленный между [CATransaction begin] и [CATransaction commit], должен быть частью транзакции.

[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
    NSLog(@"blabla");
}];

// Create the CABasicAnimation using your existing code
CABasicAnimation *myPropertyAnim = [CABasicAnimation animationWithKeyPath:@"myProperty"];
// TODO: Setup animation range
myPropertyAnim.toValue = newValue;

// The CATransaction does not observe arbitrary properties so this fails:
//myLayer.myProperty = newValue;

// Add the CAAnimation subclass during the CATransaction
[myLayer addAnimation:myPropertyAnim forKey:@"myKey"];

[CATransaction commit];

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

Проверьте этот сайт на наличие кода:

Код, на который я ссылался:

[CATransaction begin];
[topLayer addAnimation:topAnimation forKey:@"flip"];
[bottomLayer addAnimation:bottomAnimation forKey:@"flip"];
[CATransaction commit];
person Jonathan Branam    schedule 09.11.2010
comment
Я подтверждаю, что это работает, однако я немного разочарован тем, что за настраиваемыми свойствами нельзя использовать ту же магию, что и за анимируемыми свойствами. И я собираюсь запустить несколько тестов, чтобы увидеть, что произойдет, если продолжительность CATransaction будет установлена ​​на более низкое значение, чем любое из прилагаемых CAAnimations. - person romrom; 10.11.2010

Есть отличный класс под названием CAAnimationBlocks, который объясняется здесь, это категория в CAAnimation, которая позволяет вам использовать блоки завершения, как в UIView.

Вы используете его, просто позвонив:

CABasicAnimation myAnimation;
[myAnimation setCompletion:^(BOOL finished) { // Do something }];
person adamsiton    schedule 22.12.2011