Animations imbriquées de différentes durées

Bonjour !


 


je souhaiterais mettre en place l'animation suivante : 


 


- sur une durée de 2 secondes, le frame change


- sur la même durée, pendant la première moitié de l'animation, un label disparaà®t


- pendant la deuxième moitié de l'animation, un autre label apparaà®t


 


ça ne marche pas car il semble qu'il ne soit pas possible d'avoir des animations parallèles de durée différente. Je souhaitais savoir s'il y a des moyens classiques de contourner cette limitation.


 


Voici mon code



[UIView animateWithDuration:2
animations:^{
self.myView.frame = CGRectMake(100, 500, 400, 200) ;

[UIView animateWithDuration:1
animations:^{
self.firstLabel.alpha = 0 ;
} completion:^(BOOL finished) {
[UIView animateWithDuration:1
animations:^{
self.secondLabel.alpha = 1 ;
}];
}];
}];

Merci !


Réponses

  • AliGatorAliGator Membre, Modérateur

    Sors ton 2ème + 3ème "animateWithDuration:" du premier, ne le met pas à  l'intérieur du block "animations:" du premier, mais met le après, en instruction suivante, séparée.



    [UIView animateWithDuration:2 animations:^
    {
    self.myView.frame = CGRectMake(100, 500, 400, 200) ;
    }];
     
    [UIView animateWithDuration:1 animations:^
    {
    self.firstLabel.alpha = 0 ;
    } completion:^(BOOL finished) {
    [UIView animateWithDuration:1 animations:^{
    self.secondLabel.alpha = 1 ;
    }];
    }];

  • Merci ! ça marche parfaitement !


     


    Y a-t-il un moyen de ne pas "sortir" les deux mini-animations de la grande animation ?


    En gros, j'ai un code qui fait



    [UIView animateWithDuration:2 animations:^
    {
    [self.delegate doTheAnimations];
    }];


    et je n'ai que le contrôle sur la méthode `doTheAnimations`. Y'aurait-il dans ce cadre un moyen de réaliser l'animation voulue ?


     


    Merci !


  • AliGatorAliGator Membre, Modérateur

    Alors directement, non je ne pense pas, puisque la solution officielle c'est effectivement d'avoir 2 blocs d'animation en parallèle (d'où ma solution d'exécuter ton animation de 2s d'un côté et tes 2 animations d'1s de l'autre côté, de façon parallèles et indépendantes), et non pas un seul.


     


    Maintenant, tu peux aussi faire autrement. Par exemple au lieu d'utiliser [UIView animateWithDuration:animations:completion:], passer par des CAKeyframeAnimations.


     


    En effet, [UIView animateWithDuration:animations:completion:] est une méthode bien pratique car simple à  utiliser, mais du coup elle ne sait faire que des animations simples, qui font une interpolation linéaire entre la valeur actuelle de la propriété à  T=0 et la valeur finale de la propriété à  T=duration. Mais si tu veux une courbe d'animation plus complexe et plus maà®trisée, tu peux toujours utiliser CoreAnimation et les CAAnimation, ce qui n'est finalement pas si compliqué.


     


    L'idée serait alors, dans ta méthode delegate doTheAnimations, de toujours faire l'animation de la frame normalement, car pour elle une interpolation linéaire te va très bien, mais pour tes alpha, d'utiliser une CAKeyframeAnimation qui va non pas faire une interpolation linéaire de la valeur 0 en T=0 à  1 en T=2s, mais une interpolation en 2 temps (2 keyframes), la première pour passer l'alpha de 0 à  1 sur la première seconde, et la 2ème pour passer l'alpha de 1 à  ... 1 sur la 2ème seconde (donc ne plus rien changer). Et évidemment, l'inverse sur l'alpha de ton autre label.


     


    Du coup tu crées et lances ces 2 CAAnimations (une pour chaque label/alpha) dans ton doTheAnimations et ça devrait le faire. Enfin j'espère (pas testé)



  • toDoList += CoreAnimation

    ::)


  • AliGatorAliGator Membre, Modérateur
    août 2014 modifié #6

    Pour la création des CAKeyframeAnimations :



    CAKeyframeAnimation* hideFirstAnim = [CAKeyframeAnimation animationWithKeyPath:@alpha];
    // On veut aller de 1 à  0 pendant la 1ère moitié de l'animation (T=[0..0,5])
    // Puis de 0 à  0 (ne plus changer l'alpha) pendant la 2ème moitié de l'animation (T=[0,5..1])
    hideFirstAnim.values = @[; @1, @0, @0 ];
    hideFirstAnim.keyTimes = @[; @0.0, @0.5, @1.0 ];
    [label1.layer addAnimation:hideFirstAnim forKey:@hide_label_1];
     
    CAKeyframeAnimation* showAfterAnim = [CAKeyframeAnimation animationWithKeyPath:@alpha];
    // On veut aller de 0 à  0 (ne pas changer l'alpha) pendant la 1ère moitié de l'animation (T=[0..0,5])
    // Puis de 0 à  1 pendant la 2ème moitié de l'animation (T=[0,5..1])
    showAfterAnim.values = @[; @0, @0, @1 ];
    showAfterAnim.keyTimes = @[; @0.0, @0.5, @1.0 ];
    [label2.layer addAnimation:hideFirstAnim forKey:@show_label_2];

    Voilà , après j'ai pas testé y'a peut-être une ou 2 conneries à  rajouter pour tuner finement le bouzin, mais l'idée est là .


Connectez-vous ou Inscrivez-vous pour répondre.