2012-04-15 2 views
7

Я создал 2 NSAnimation объекты с переворотом взгляда с другим видом. Я бы хотел запустить две эти анимации одновременно. Я не могу использовать NSViewAnimation, так как теперь он об анимации любых свойств вида.Есть ли способ запустить 2 объекта NSAnimation одновременно?

Вот создание анимации:

self.animation = [[[TransitionAnimation alloc] initWithDuration:1.0 animationCurve:NSAnimationEaseInOut] autorelease]; 
[self.animation setDelegate:delegate]; 
[self.animation setCurrentProgress:0.0]; 

[self.animation startAnimation]; 

Я пытался связать 2 анимации, но, вероятно, он не работает по какой-то причине. Я взял пример из: Apple developer site

настройки NSAnimation объекта для использования NSAnimationNonblocking не показывает анимацию на все ...

EDIT: Вторая анимация точно так же, как и первым, и созданный в в том же месте создается первое.

TransitionAnimation является подклассом NSAnimation, где setCurrentProgress выглядит так:

- (void)setCurrentProgress:(NSAnimationProgress)progress { 
    [super setCurrentProgress:progress]; 
    [(NSView *)[self delegate] display];  
} 

delegate в этом случае, что в его функции DrawRect применяется NSView зависящее от времени CIFilter на CIImage. Проблема в том, что он работает синхронно, а вторая анимация начинается сразу после первого. Есть ли способ запустить их одновременно?

+1

Где вторая анимация? И каким образом дела не работали? –

ответ

17

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

Я создал простой sample project, который показывает, как анимировать несколько свойств представления одновременно, используя протокол NSAnimatablePropertyContainer.

Все, что вам нужно сделать для успешного обновления, это убедиться, что при изменении любого из изменяемых свойств вызывается setNeedsDisplay:YES. Затем вы можете получить значения этих свойств в своем методе drawRect: и обновить анимацию на основе этих значений.

Если вы хотите простое значение прогресса, которое аналогично тому, как работают вещи с NSAnimation, вы можете определить progress собственности на ваш взгляд, а затем сделать что-то вроде этого:

yourView.progress = 0; 
[yourView.animator setProgress:1.0]; 

Вы можете получить доступ к self.progress в вашем методе drawRect:, чтобы узнать текущее значение анимации.

+0

Спасибо большое! Я не знал об этом. Как-то я не дошел до него в поиске Google. Попробуй и расскажешь. –

+0

Мне просто интересно: если у нас проблемы с производительностью (с низкой частотой кадров) с NSAnimation, возможно ли применение этого протокола? – Zakman411

+0

Это зависит от того, что вызывает низкую частоту кадров. Прокси-сервер анимации не является волшебной пулей и все равно будет рисовать ваши взгляды, поэтому, если рисование/компоновка будут медленными, то переход к этой технологии не будет иметь большого значения. Скорее всего, вам понадобится использовать высокопроизводительную технологию рендеринга, такую ​​как Core Animation, которая специально предназначена для рендеринга анимации. –

Смежные вопросы