2012-05-08 3 views
10

Dies sollte einfach sein, aber ich habe Probleme beim Drehen einer UIImageView eine volle 360 ​​Grad, für immer wiederholt.Drehen UIImageView im Uhrzeigersinn

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveLinear | UIViewAnimationOptionBeginFromCurrentState animations:^{ 
    self.reloadButton.imageView.transform = CGAffineTransformRotate(self.reloadButton.imageView.transform, -M_PI); 
} completion:^(BOOL finished) { 

}]; 

die Dokumentation Nach der Signedness des Winkels I zu CGAffineTransformRotate passieren bestimmt die Richtung der Drehung, aber der obige Code dreht sich gegen den Uhrzeigersinn. Gleiches mit M_PI.

Der Winkel im Bogenmaß, um den diese Matrix die Koordinaten Systemachsen dreht. In iOS gibt ein positiver Wert eine Drehung entgegen dem Uhrzeigersinn an und ein negativer Wert gibt die Drehung im Uhrzeigersinn an. In Mac OS X gibt ein positiver Wert eine Drehung im Uhrzeigersinn an und ein negativer Wert eine Drehung gegen den Uhrzeigersinn.

+0

Was passiert, wenn die Rotation auf der imageViews Schicht mit einem CATransform3D tun? –

+0

haben Sie versucht, sich um andere Winkel zu drehen (sagen wir 180 Grad)? – giorashc

+0

@David Danke für den Vorschlag, aber dies führte zu den gleichen Ergebnissen: self.reloadButton.imageView.layer.transform = CATransform3DMakeRotation (-M_PI, 0, 0, 1); – Morrowless

Antwort

14

Christoph geht bereits den richtigen Weg, aber es gibt einen weitaus besseren Weg, um es in Schwung zu halten, ohne es in den Animationsdelegaten jedes Mal neu zu starten, wenn es endet. Das ist einfach falsch.

Setzen Sie einfach die Eigenschaft repeatCount Ihrer Animation auf HUGE_VALF.

CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
animation.fromValue = @0.0f; 
animation.toValue = @(2*M_PI); 
animation.duration = 0.5f;    // this might be too fast 
animation.repeatCount = HUGE_VALF;  // HUGE_VALF is defined in math.h so import it 
[self.reloadButton.imageView.layer addAnimation:animation forKey:@"rotation"]; 

Wie bereits erwähnt in the documentation, das ist die Animation für immer zu wiederholen, führen wird.

+1

Ok, habe nicht wirklich darüber nachgedacht, weil 270 Grad für mich genug waren. Das Einstellen der Wiederholungszahl ist viel besser, ich werde mich entsprechend ändern. – Christoph

+1

Danke für den Code! funktioniert GREAT – eric

+0

Verwenden Sie 'CGFLOAT_MAX' anstatt etwas zu importieren. –

1

Leider verpassten ersten Teil dreht Ansicht gerade fein kleineren Winkel mit:

[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveLinear | UIViewAnimationOptionBeginFromCurrentState animations:^{ 
     redView.transform = CGAffineTransformRotate(redView.transform, M_PI_2); 
    } completion:^(BOOL finished) { 

    }]; 

Ich konnte keine sinnvolle Erklärungen finden, warum es mit M_PI ausfällt.

+0

Wiederholen ist genau das, was ich will, das Problem ist, dass es nicht im Uhrzeigersinn dreht. – Morrowless

+0

Ich denke es ist, weil der Endzustand der Rotation ist der gleiche wie der ursprüngliche Zustand – giorashc

1

Ich stieß auf das gleiche Problem vor einer Weile. Ich erinnere mich nicht, den Grund für das Problem, aber das ist meine Lösung:

/** 
* Incrementally rotated the arrow view by a given angle. 
* 
* @param degrees Angle in degrees. 
* @param duration Duration of the rotation animation. 
*/ 
- (void)rotateArrowViewByAngle:(CGFloat)degrees 
        withDuration:(NSTimeInterval)duration { 

    CABasicAnimation *spinAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    spinAnimation.fromValue = [NSNumber numberWithFloat:self.currentAngle/180.0 * M_PI]; 
    spinAnimation.toValue = [NSNumber numberWithFloat:degrees/180.0 * M_PI]; 
    spinAnimation.duration = duration; 
    spinAnimation.cumulative = YES; 
    spinAnimation.additive = YES; 
    spinAnimation.removedOnCompletion = NO; 
    spinAnimation.delegate = self; 
    spinAnimation.fillMode = kCAFillModeForwards; 

    [self.arrowView.layer addAnimation:spinAnimation forKey:@"spinAnimation"]; 

    self.currentAngle = degrees; 
} 

und dann können Sie die Delegatmethoden

- (void)animationDidStart:(CAAnimation *)theAnimation 
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag 

verwenden, um es zu drehen zu halten drehen. Grad und Dauer Parameter können auch wirklich hohe Zahlen sein ... wenn das genug ist.

UPDATE:
Wie Yinkou angegeben,

spinAnimation.repeatCount = HUGE_VALF;  // HUGE_VALF is defined in math.h so import it 

ist viel besser, dass die Animation in den Delegaten neu zu starten.

BITTE BEACHTEN:
self.currentAngle ist eine Eigenschaft, die an die aktuelle Endrotation erinnert.
Ich brauchte das, um die Ansicht nach links und rechts herum zu drehen.