Есть ли способ запустить 2 объекта NSAnimation одновременно?
Я создал 2 NSAnimation
объекты переворачивания представления с другим представлением. Я хотел бы запустить 2 эти анимации одновременно. Я не могу использовать NSViewAnimation
, поскольку теперь речь идет об анимации любого из свойств представления.
Вот создание анимации:
self.animation = [[[TransitionAnimation alloc] initWithDuration:1.0 animationCurve:NSAnimationEaseInOut] autorelease];
[self.animation setDelegate:delegate];
[self.animation setCurrentProgress:0.0];
[self.animation startAnimation];
Я пытался связать 2 анимации, но, возможно, по какой-то причине это не сработало. Я взял пример с: сайта разработчика Apple
настройка NSAnimation
объект для использования NSAnimationNonblocking
не показывает анимацию вообще...
РЕДАКТИРОВАТЬ: вторая анимация точно так же, как первая и создается в том же месте, где создается первая.
TransitionAnimation
это подкласс NSAnimation
, где setCurrentProgress
выглядит так:
- (void)setCurrentProgress:(NSAnimationProgress)progress {
[super setCurrentProgress:progress];
[(NSView *)[self delegate] display];
}
delegate
является NSView
в этом случае, который в своей функции drawRect применяет зависящий от времени CIFilter
на CIImage
, Проблема в том, что он работает синхронно, и вторая анимация начинается сразу после окончания первой. Есть ли способ запустить их одновременно?
1 ответ
NSAnimation
на самом деле не лучший выбор для анимации нескольких объектов и их свойств одновременно.
Вместо этого вы должны привести свои взгляды в соответствие с NSAnimatablePropertyContainer
протокол.
Затем вы можете настроить несколько пользовательских свойств в качестве анимируемых (в дополнение к свойствам, уже поддерживаемым NSView
), а затем вы можете просто использовать свои взгляды animator
прокси для анимации свойств:
yourObject.animator.propertyName = finalPropertyValue;
Помимо упрощения анимации, она также позволяет анимировать несколько объектов одновременно, используя NSAnimationContext
:
[NSAnimationContext beginGrouping];
firstObject.animator.propertyName = finalPropertyValue1;
secondObject.animator.propertyName = finalPropertyValue2;
[NSAnimationContext endGrouping];
Вы также можете установить продолжительность и предоставить блок обработчика завершения:
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.5];
[[NSAnimationContext currentContext] setCompletionHandler:^{
NSLog(@"animation finished");
}];
firstObject.animator.propertyName = finalPropertyValue1;
secondObject.animator.propertyName = finalPropertyValue2;
[NSAnimationContext endGrouping];
NSAnimation
а также NSViewAnimation
классы намного старше, чем поддержка прокси аниматора, и я настоятельно рекомендую вам отойти от них, если это возможно. Поддерживая NSAnimatablePropertyContainer
Протокол намного проще, чем управлять всеми NSAnimation
делегировать вещи. Поддержка Lion для пользовательских функций синхронизации и обработчиков завершения означает, что больше нет необходимости делать это.
Для стандарта NSView
объект, если вы хотите добавить поддержку анимации для свойства в вашем представлении, вам просто нужно переопределить +defaultAnimationForKey:
метод на ваш взгляд и вернуть анимацию для свойства:
//declare the default animations for any keys we want to animate
+ (id)defaultAnimationForKey:(NSString *)key
{
//in this case, we want to add animation for our x and y keys
if ([key isEqualToString:@"x"] || [key isEqualToString:@"y"]) {
return [CABasicAnimation animation];
} else {
// Defer to super's implementation for any keys we don't specifically handle.
return [super defaultAnimationForKey:key];
}
}
Я создал простой пример проекта, который показывает, как анимировать несколько свойств представления одновременно, используя NSAnimatablePropertyContainer
протокол.
Все, что нужно для успешного обновления, - это убедиться, что setNeedsDisplay:YES
Вызывается, когда любое из анимируемых свойств изменяется. Затем вы можете получить значения этих свойств в вашем drawRect:
метод и обновить анимацию на основе этих значений.
Если вам нужно простое значение прогресса, аналогичное тому, как все работает NSAnimation
Вы могли бы определить progress
Свойство на ваш взгляд, а затем сделать что-то вроде этого:
yourView.progress = 0;
[yourView.animator setProgress:1.0];
Вы можете получить доступ self.progress
в вашем drawRect:
Метод, чтобы узнать текущее значение анимации.