2009-02-12 12 views
28

Ich schreibe eine iPhone App, und ich habe ein Bild, das ich gerne nach außen strudeln würde.Kann ich mit CGAffineTransformMakeRotation eine Ansicht um mehr als 360 Grad drehen?

Derzeit sieht mein Code wie folgt aus (in einem beginAnimations umhüllter/commitAnimations Block):

scale = CGAffineTransformScale(CGAffineTransformIdentity, 5.0f, 5.0f); 
swirl = CGAffineTransformRotate(scale, M_PI); 
[player setTransform:swirl];  
[player setAlpha:0.0f]; 

Aber ich finde, dass, wenn ich versuche, den Winkel der Drehung zu ändern, sagen wir, 4 * M_PI, es dreht sich überhaupt nicht. Ist es möglich, mit CGAffineTransformRotate eine 720˚ Rotation zu erreichen, oder muss ich zu einer anderen Technologie wechseln?

Wenn ich zu einer anderen Technologie wechseln muss, empfehlen Sie, einen anderen Thread (oder einen Timer) zu verwenden, um die Animation selbst zu machen, oder wäre OpenGL eine bessere Route?

Danke,
Blake.

Antwort

64

Sie können eine Ansicht um eine bestimmte Anzahl von Radianten drehen, unabhängig davon, ob sie weniger als eine volle oder viele Vielfache einer vollen Drehung beträgt, ohne die Drehung in Teile aufteilen zu müssen. Als Beispiel wird der folgende Code eine Ansicht einmal pro Sekunde für eine bestimmte Anzahl von Sekunden drehen. Sie können es leicht ändern, um eine Ansicht um eine bestimmte Anzahl von Rotationen oder um eine bestimmte Anzahl von Radianten zu drehen.

- (void) runSpinAnimationWithDuration:(CGFloat) duration; 
{ 
    CABasicAnimation* rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ]; 
    rotationAnimation.duration = duration; 
    rotationAnimation.cumulative = YES; 
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 

    [myView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 
+0

Das funktioniert. Danke, dass du es gepostet hast und darauf bestanden hast, die Beiträge anderer Leute zu kommentieren! Ich wollte meine Animation teilen! – Dimitris

+0

Ich habe sie auch geteilt und das schien einfach nicht richtig zu sein. – mahboudz

+0

stellen Sie sicher, dass Sie dies für transform.rotation.z tun Ich hatte Probleme, es einfach zu tun, mit CATransform3DMakeRotation zu transformieren. Ich habe immer wieder in "Gimbal Lock" gerannt, als ich die Make-Rotation-Funktion benutzt habe. Wenn ich transform.rotation.z wie oben beschrieben benutze, funktioniert es wunderbar! – Jay

5

Sie können, aber Sie müssen Ihre Animation in Halbkreisrotationen aufteilen. Ich gebe ein Beispiel dafür als Antwort auf this question unter Verwendung einer wiederholenden CABasicAnimation, die auf die Schicht unterhalb der Ansicht angewendet wurde. Wie ich vorschlage, wäre es wahrscheinlich besser, diese Halbdrehungen als Teile einer CAKeyframeAnimation zu strukturieren, weil die Animation glatter wäre (in meinem Beispiel gibt es eine leichte Kopplung zwischen Halbdrehungen), und das könnte man tun eine schöne Beschleunigung/Verzögerung am Anfang und am Ende.

+0

Kühl. Dies scheint zu tun, was ich mir erhofft hatte, und ich denke, ich kann auch eine Skalierungstransformation hinzufügen und eine Benachrichtigung an meine Klasse zurückbekommen. Danke! – bwinton

+2

Es ist falsch zu sagen, dass Sie eine Animation in Halbkreisrotationen aufteilen müssen. Siehe meine Antwort. – mahboudz

+0

Sie tun, wenn Sie sich auf einen CATransform3D als den Wert verlassen, den Sie animieren. Ich habe nicht über Ihre Herangehensweise nachgedacht und die Keypath-Erweiterungen verwendet, die Core Animation für die Transformationsstrukturfelder bietet. Du hast Recht, das ist wahrscheinlich ein sauberer Weg, um das zu erreichen. –

5

Antwort zum Titel: Ja, CGAffineTransform kann mehr als 360 Grad gut drehen.
Antwort auf Frage: Ja, aber Sie können es nicht animieren, weil es nichts zu animieren gibt.

Denken Sie daran, dass the affine transformation is a matrix, und dass eine Rotationsmatrix enthält die Sinus- und Kosinus-Nummern vorberechnet. Es ist, als ob Sie sagte:

CGFloat angle = 4.0 * M_PI; 
NSAffineTransformStruct matrix = { 
    .m11 = cos(angle), 
    .m12 = sin(angle), 
    .m21 = -sin(angle), 
    .m22 = cos(angle), 
    .tx = 0.0, 
    .ty = 0.0 
}; 
NSAffineTransform *transform = [NSAffineTransform transform]; 
[transform setTransformStruct:matrix]; 

Nun lassen Sie uns für cos und sin einige Beispielwerte überprüfen:

  • cos(0π) = 1
  • sin(0π) = 0
  • cos(2π) = 1
  • sin(2π) = 0
  • cos(4π) = 1
  • sin(4π) = 0

Denken Sie daran, die Matrix nicht den Winkel enthält - es enthält nur den Kosinus und Sinus. Und diese Werte ändern sich nicht von einem Vielfachen eines Kreises zum anderen. Daher gibt es nichts zu animieren.

(Beachten Sie, dass Calculator.app falsche Ergebnisse für cos (xπ) und sin gibt (xπ). Versuchen Sie Grapher, calc oder Google.)

Sie müssen die Animation in Fraktionen eines Kreises spalten. Die Halbkreise, die Brad Larson vorgeschlagen hat, werden gut funktionieren.

+2

Sie müssen die Animation nicht teilen. Siehe meine Antwort. – mahboudz

Verwandte Themen