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

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];

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

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

CABasicAnimation myAnimation;
[myAnimation setCompletion:^(BOOL finished) { // Do something }];
Другие вопросы по тегам