Анимировать пользовательские свойства 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];
Извините, что у меня нет настройки проекта, чтобы легко проверить это сейчас, но я верю, что это сработает.
Проверьте эти сайты на код:
- http://www.mentalfaculty.com/mentalfaculty/Blog/Entries/2010/9/22_FLIPPIN_OUT_AT_NSVIEW.html
- http://boondoggle.atomicwang.org/lemurflip/MFFlipController.m
Код, на который я ссылался:
[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 }];