2010-08-12 3 views
8

J'anime un pendule qui oscille de 0 degré à 200 degrés maximum puis revient à nouveau. Le problème est que si le pendule dépasse 180 degrés, il revient à 0 par la route la plus courte qui doit continuer dans le sens des aiguilles d'une montre. Et j'aimerais que ça se fasse dans le sens inverse des aiguilles d'une montre. Voici mon code: (« droit » est un booléen qui est vrai lorsque le pendule oscille de gauche à droite)Rotation dans le sens des aiguilles d'une montre/anti-horaire pour un CABAnimation d'un UIImageView

- (void)swingPendulum { 
    CABasicAnimation *rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    if (right) 
     rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMax)]; 
    else 
     rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMin)];        
    rotationAnimation.duration = 1.0; 
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.delegate = self; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
    rotationAnimation.removedOnCompletion = NO; 

    [pendulum.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 

Toute idée comment je peux faire ce travail? C'est la dernière pièce de mon puzzle swingomètre qui fonctionne par ailleurs très bien: D Merci!

Michael

Répondre

8

Pour l'obtenir pour aller dans le sens antihoraire, vient de mettre x à une valeur négative (ajouter - en face) où vous voulez

rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(x)]; 
+0

Merci pour la réponse, mais je n'ai pas l'air de faire une différence. Le mettre à une valeur -ive semble juste rendre l'animation à la fin ...Je pense que je devrais peut-être le réécrire pour utiliser un NSTimer et animer la chose image par image ... – Smikey

+0

En fait, vous avez raison - puisque kMin est actuellement réglé sur -20, donc cela ne fait qu'effectuer le balancement du pendule anti-horaire, mais seulement si elle ne dépasse pas 180 degrés. Si elle dépasse 180, peu importe la valeur que je lui donne (-180, -90, 90 etc.), elle continue toujours dans le sens des aiguilles d'une montre, même si ce n'est pas la plus courte ... D'autres idées? – Smikey

+1

AAAAH, si je le mets à une valeur comme -380 cependant, cela fonctionne. Je ne suis pas vraiment sûr pourquoi, mais j'ai juste ajouté une condition qui bascule le toValue selon si le swing initial passe 180 degrés. Merci pour votre aide! – Smikey

0

Je ne sais pas exactement ce que le problème est, mais si vous utilisez la fonction d'inversion automatique de l'animation, vous pouvez probablement simplifier et le faire tourner (balançoire) avant et en arrière. Cela fonctionne pour moi:

CABasicAnimation* rotationAnimation = 
      [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
[rotationAnimation setToValue:[NSNumber numberWithFloat:DegreesToRadians(200.0)]]; 
[rotationAnimation setDuration:1.0]; 
[rotationAnimation setRepeatCount:HUGE_VALF]; // Repeat forever 
[rotationAnimation setAutoreverses:YES]; // Return to starting point 

[[pendulum layer] addAnimation:rotationAnimation forKey:nil]; 
+0

Une bonne idée, mais le swing inverse n'est pas une inversion exacte de l'oscillation vers l'avant. C'est à dire. le swing vers l'avant commence à 0, mais le swing inverse revient à -20. Donc, je préfère appeler une fonction qui la ramène de sa transformation actuelle à un angle spécifique. Je n'essaie pas de faire un pendule exactement, plutôt un swingomètre de style de jeu de golf - le joueur l'arrête une fois sur le chemin de la puissance et de nouveau sur le chemin de la précision. Il fonctionne parfaitement à moins que la barre ne dépasse 180 degrés sur le chemin vers le haut, après quoi il va continuer dans le sens inverse des aiguilles d'une montre à 0, plutôt que de renverser .. Donc je dois forcer est en quelque sorte – Smikey

1

Essayez de régler les quelque chose comme

rotationAnimation.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ]; 

En utilisant la valeur de transformation des fonctions, des animations peuvent effectuer la propriété transform d'une couche en utilisant des transformations arbitraires de chaque composant (pas de normalisation à 360 °) et concaténer dans le normalement lorsque plusieurs animations sont appliquées en même temps. Vous utilisez une fonction de transformation de valeur qui pivote de 0 ° à 180 ° autour de l'axe z en créant une fonction CAValueTransform spécifiant kCAValueFunctionRotateZ, puis en créant une animation avec une valeur fromValue de 0, une valeur toValue de M_PI et définissez la Valeur de l'animationTransforme la propriété vers l'instance de transformation de la valeur.

+0

Merci. Je suis un peu réticent à changer l'approche que j'utilise déjà à moins qu'il n'y ait aucun moyen de le réparer, car j'ai beaucoup d'autre code qui repose sur les méthodes que j'ai déjà utilisées. Comme mentionné ci-dessus, je suis en train de créer un swingomètre de style jeu de golf, plutôt qu'un pendule, donc à tout moment l'utilisateur peut interrompre le swing sur le chemin (pour déterminer la puissance) et il va revenir en arrière, afin que l'utilisateur puisse Interrompez à nouveau (pour déterminer la précision). J'ai toutes ces fonctionnalités, à part le fait que si l'utilisateur laisse la barre osciller de plus de 180 degrés, il ne se retourne pas, il avance plutôt. – Smikey

+0

Essayez de le configurer et de voir si cela fonctionne? J'ai l'impression que ça devrait l'être. –

+0

Je l'ai fait - ça a commencé à se comporter assez étrangement ... Je vais avoir un peu plus d'un violon et revenir! – Smikey

1

Je pense que vous devez utiliser ce code:

[rotationAnimation.byValue = [NSNumber numberWithFloat:degreesToRadians(kMax/2))]; 
[rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadians(kMin)]; 
Questions connexes