Effet de rebond (enchainement de plusieurs animations)

allianallian Membre
04:00 modifié dans API UIKit #1
Bonjour,
j'aimerais comprendre pourquoi lorsque j'enchaine plusieurs blocks d'animations, certains ne fonctionnent pas enfin l'action se fait mais sans l'effet.

J'ai essayé de jouer avec les duration et les delay mais rien n'y fait.

J'essaye en faite de faire un petit effet de rebon d'une UIViewController, pour cela je lui passe une frame d'origine et apres je la déplace sur l'axe des Y avec en plus un fade in/out mais celle ci apparait directement en bas et ne fait que remonter.

Voila mon code :

CGRect hop = CGRectMake(210, 0, 60, 30);<br />					theHighlight.view.frame = hop;<br />					<br />					[UIView beginAnimations:nil context:nil];<br />					[UIView setAnimationDuration:0.5];<br />					[self.theHighlight.view setAlpha:100];<br />					[UIView commitAnimations];<br />					<br />					[UIView beginAnimations:nil context:nil];<br />					[UIView setAnimationDuration:0.5];<br />					CGRect hop2 = CGRectMake(210, 8, 60, 30);<br />					theHighlight.view.frame = hop2;<br />					[UIView commitAnimations];<br />					<br />					[UIView beginAnimations:nil context:nil];<br />					[UIView setAnimationDuration:0.5];<br />					[UIView setAnimationDelay: 0.5];<br />					CGRect hop3 = CGRectMake(210, 2, 60, 30);<br />					theHighlight.view.frame = hop3;<br />					[UIView commitAnimations];<br />					<br />					[UIView beginAnimations:nil context:nil];<br />					[UIView setAnimationDuration:2];<br />					[UIView setAnimationDelay: 0.5];<br />					[self.theHighlight.view setAlpha:0];<br />					[UIView commitAnimations];<br />


Merci les amis  8--)

Réponses

  • AliGatorAliGator Membre, Modérateur
    04:00 modifié #2
    On ne peut pas enchaà®ner les animations ainsi, car le code des animations n'est pas séquentiel et surtout n'est pas synchrone. Dans ton cas ça doit faire un truc un peu bizarre genre toutes les animations sont lancées en même temps, ou alors seulement la dernière est jouée, plus probablement

    Il faut que tu ne lances que la première animation, puis utilises la méthode de delegate animationDidStop: pour détecter quelle animation vient de s'arrêter et lancer la suivante.

    Note : comme CAAnimation est KVC-compliant, tu peux rajouter les clés que tu veux à  une CAAnimation.
    Both CALayer and CAAnimation are key-value coding compliant container classes, allowing you to set values for arbitrary keys. That is, while the key “foo” is not a declared property of the CALayer class, however you can still set a value for the key “foo” as follows:[...]

    Cela peut s'avérer très pratique pour par exemple associer à  chaque CAAnimation un nom ou autre, qui te servira à  identifier l'animation dans le [tt]animationDidStop:[/tt] pour savoir quelle animation vient de se terminer et donc quelle est la nouvelle animation à  lancer à  sa suite...
  • allianallian Membre
    04:00 modifié #3
    Je comprends bien comment CAAnimation fonctionne, mais du coup sur quel objet j'appelle la méthode animationDidStop ?

    Parce que la je n'ai pas d'instance de CAAnimation, dois en créer un ?
  • AliGatorAliGator Membre, Modérateur
    04:00 modifié #4
    Ah oui pardon tu utilises les méthodes de UIView pour les animations...

    Bah alors plusieurs possibilités :
    - soit oui tu "convertis" ça en CAAnimation et fait comme je t'ai dit

    - soit tu utilises le même principe que je t'ai expliqué mais en utilisant les méthodes de UIView, à  savoir setAnimationDelegate: et setAnimationDidStopSelector: pour fixer la méthode à  appeler à  la fin de l'animation, et l'objet (delegate) sur lequel appeler cette méthode (très certainement self, ton même objet qui gère déjà  les anims, j'imagine). En plus tu peux du coup mettre un "didEndSelector" différent pour chaque animation... Donc initier ta première animation en lui fixant son animationDelegate+animationDidEndSelector, selector dans lequel tu mettras ta 2e partie d'animation (ton 2e bloc [UIView startAnimation:context]...[UIView commitAnimations]) et pour qui tu fixera un autre didEndSelector, qui démarrera ton 3e bloc / ta 3e partie d'animation, etc.

    - Ou sinon tu modifies la startDate de chacun de tes bouts d'animations, de sorte que la 2e partie d'animation ne démarre qu'après un temps T1 égal à  la durée de la 1ère partie, et que la 3e partie démarre après un temps T = T1+T2 somme des temps des 2 premières parties, etc... mais bon c'est moins "sûr" comme méthode, c'est possible que ce soit moins fluide au cas où il y ait un petit décalage dans les durées des anims... alors qu'avec les didEndSelector t'es plus sûr.
  • allianallian Membre
    04:00 modifié #5
    Merci ça marche nikel !
    Par contre comme j'ai deux controller qui utilisent les meme animations j'aurais voulu utiliser le animationID pour pas avoir à  ecrire des méthodes en double mais je n'arrive pas à  comprendre comment le passer en argument dans mon selector.

    Tiré de la doc d'apple :

    "animationID

    An optional application-supplied identifier. The same argument passed to the beginAnimations:context: method. This argument can be nil."

    Si j'appelle comme ça ca passe à  la compil mais la méthode labelScaleUp n'est jamais appelé.

    [UIView setAnimationDidStopSelector:@selector(labelScaleUp: animationID:finished:context:)];
    


    Et si j'essaye de lui passer une NSSrtring j'ai une erreur à  la compil.

    Quelqu'un l'a déjà  utilisé ?
    Merci
Connectez-vous ou Inscrivez-vous pour répondre.