Анимировать пользовательские свойства CALayer внутри CATransaction - PullRequest
8 голосов
/ 08 ноября 2010

До сих пор я был в состоянии анимировать пользовательские свойства моего подкласса 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 в содержащее представление.

Ответы [ 2 ]

10 голосов
/ 09 ноября 2010

Я считаю, что, основываясь на чтении исходного кода, вы все равно можете использовать 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];
1 голос
/ 22 декабря 2011

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

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

CABasicAnimation myAnimation;
[myAnimation setCompletion:^(BOOL finished) { // Do something }];
...