2012-04-15 10 views
7

Ich habe 2 NSAnimation Objekte erstellt, um die Ansicht mit einer anderen Ansicht zu spiegeln. Ich möchte 2 Animationen gleichzeitig ausführen. Ich kann NSViewAnimation nicht verwenden, da es jetzt darum geht, alle Ansichtseigenschaften zu animieren. HierGibt es eine Möglichkeit, 2 NSAnimation-Objekte gleichzeitig auszuführen?

ist die Animation Schöpfung:

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

[self.animation startAnimation]; 

Ich habe versucht 2 Animationen zu verknüpfen, aber wahrscheinlich war es aus irgendeinem Grund nicht funktionieren. Ich habe ein Beispiel aus: Apple developer site

das NSAnimation Objekt Konfiguration NSAnimationNonblocking zu verwenden, ist überhaupt keine Animation zeigen ...

EDIT: Die zweite Animation ist genau das gleiche wie die ersten und erstellt in Derselbe Ort, an dem der erste erschaffen wurde.

TransitionAnimation ist eine Unterklasse von NSAnimation, wo die setCurrentProgress so aussieht:

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

die delegate ist NSView in diesem Fall, der in seiner Funktion drawRect gilt eine zeitabhängige CIFilter auf einem CIImage. Das Problem ist, dass es synchron läuft und die zweite Animation direkt nach dem Ende des ersten beginnt. Gibt es eine Möglichkeit, sie gleichzeitig auszuführen?

+1

Wo ist die zweite Animation? Und auf welche Weise haben die Dinge nicht funktioniert? –

Antwort

17

NSAnimation ist nicht wirklich die beste Wahl für die gleichzeitige Animation mehrerer Objekte und ihrer Eigenschaften.

Stattdessen sollten Sie Ihre Ansichten dem NSAnimatablePropertyContainer Protokoll entsprechen.

Sie können dann mehrere benutzerdefinierte Eigenschaften als animierbaren (zusätzlich zu den Eigenschaften bereits unterstützt von NSView), und dann können Sie einfach Ihre Ansichten verwenden animator Proxy zu animieren, die Eigenschaften ein:

yourObject.animator.propertyName = finalPropertyValue; 

Apart Animation sehr einfach aus zu machen, ermöglicht es Ihnen auch mehrere Objekte gleichzeitig mit einer NSAnimationContext animieren:

[NSAnimationContext beginGrouping]; 
firstObject.animator.propertyName = finalPropertyValue1; 
secondObject.animator.propertyName = finalPropertyValue2; 
[NSAnimationContext endGrouping]; 

Sie können auch die Dauer einstellen und einen Abschluss-Handler blo liefern ck:

[NSAnimationContext beginGrouping]; 
[[NSAnimationContext currentContext] setDuration:0.5]; 
[[NSAnimationContext currentContext] setCompletionHandler:^{ 
    NSLog(@"animation finished"); 
}]; 
firstObject.animator.propertyName = finalPropertyValue1; 
secondObject.animator.propertyName = finalPropertyValue2; 
[NSAnimationContext endGrouping]; 

Die NSAnimation und NSViewAnimation Klassen sind viel älter als die Unterstützung Animator Proxy und ich empfehle, dass Sie von ihnen wegbewegen, wenn möglich. Unterstützung für die NSAnimatablePropertyContainer Protokoll ist viel einfacher als die Verwaltung aller NSAnimation Delegate Zeug. Die Lion-Unterstützung für benutzerdefinierte Timing-Funktionen und Completion-Handler bedeutet, dass dies wirklich nicht mehr nötig ist.

Für ein Standard-NSView Objekt, wenn Sie Unterstützung für Animationen auf eine Eigenschaft in Ihrer Ansicht hinzufügen mag, müssen Sie nur die +defaultAnimationForKey: Methode Ihrer Ansicht nach außer Kraft zu setzen und eine Animation für die Eigenschaft zurück:

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

Ich habe eine einfache sample project erstellt, die zeigt, wie mehrere Eigenschaften einer Ansicht gleichzeitig mit dem NSAnimatablePropertyContainer Protokoll zu animieren.

Alles, was Sie für eine erfolgreiche Aktualisierung benötigen, ist sicherzustellen, dass setNeedsDisplay:YES aufgerufen wird, wenn eine der animierbaren Eigenschaften geändert wird. Sie können dann die Werte dieser Eigenschaften in Ihrer drawRect:-Methode abrufen und die Animation basierend auf diesen Werten aktualisieren.

Wenn Sie einen einfachen Fortschritt Wert wollen, die auf die Art und Weise analog ist, die Dinge mit NSAnimation arbeiten, könnten Sie ein progress Eigentum auf Ihrer Ansicht definieren und dann so etwas tun:

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

Sie können dann self.progress zugreifen in Ihrer drawRect: Methode, um den aktuellen Wert der Animation herauszufinden.

+0

Vielen Dank! Ich war mir dessen nicht bewusst. Irgendwie habe ich es bei der Google-Suche nicht erreicht. Versuche es und lass es dich wissen. –

+0

Ich bin nur neugierig: Wenn wir Leistung (niedrige Bildrate) Probleme mit NSAnimation haben, würde die Anwendung dieses Protokolls möglicherweise helfen? – Zakman411

+0

Das hängt davon ab, was die niedrige Bildrate verursacht. Der Animationsproxy ist keine magische Kugel und lässt Ihre Ansichten immer noch zeichnen. Wenn das Zeichnen/Compositing langsam ist, macht das Verschieben auf diese Technologie keinen großen Unterschied. Wahrscheinlicher ist, dass Sie eine Rendering-Technologie mit höherer Leistung verwenden müssen, z. B. Core Animation, die speziell für die reibungslose Wiedergabe von Animationen entwickelt wurde. –

Verwandte Themen