Comment créer une animation de rebond UIView?

92

J'ai le CATransition suivant pour un UIView appelé finalScoreView, ce qui le fait entrer dans l'écran par le haut:

CATransition *animation = [CATransition animation];
animation.duration = 0.2;
animation.type = kCATransitionPush;
animation.subtype = kCATransitionFromBottom;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

[gameOver.layer addAnimation:animation forKey:@"changeTextTransition"];
[finalScoreView.layer addAnimation:animation forKey:@"changeTextTransition"];

Comment puis-je faire en sorte qu'il rebondisse une fois après sa descente, puis reste immobile? Il devrait toujours entrer dans l'écran par le haut, mais rebondir lorsqu'il descend.

Toute aide serait très appréciée, merci!

user3127576
la source
3
Visez-vous iOS7 et supérieur? Si tel est le cas, vous pouvez tirer parti de UIKit Dynamics
WDUK

Réponses:

144

Avec iOS7 et UIKit Dynamics, il n'est plus nécessaire d'utiliser CAKeyframeAnimationsouUIView animations!

Jetez un œil à l'application UIKit Dynamics Catalog d'Apple . Alternativement, Teehanlax a un tutoriel clair et concis avec le projet complet dans github . Si vous voulez un didacticiel plus détaillé sur les tenants et les aboutissants de la dynamique, le didacticiel Ray Winderlich est parfait . Comme toujours, les documents Apple sont un excellent premier arrêt, alors consultez la référence de la classe UIDynamicAnimator dans les documents.

Voici un peu du code du tutoriel Teenhanlax:

self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

UIGravityBehavior* gravityBehavior = 
                [[UIGravityBehavior alloc] initWithItems:@[self.redSquare]];
[self.animator addBehavior:gravityBehavior];

UICollisionBehavior* collisionBehavior = 
                [[UICollisionBehavior alloc] initWithItems:@[self.redSquare]]; 
collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;
[self.animator addBehavior:collisionBehavior];

UIDynamicItemBehavior *elasticityBehavior = 
                [[UIDynamicItemBehavior alloc] initWithItems:@[self.redSquare]];
elasticityBehavior.elasticity = 0.7f;
[self.animator addBehavior:elasticityBehavior];

et voici les résultats

Rebond carré

UIKit Dynamics est un ajout très puissant et facile à utiliser à iOS7 et vous pouvez en tirer une superbe interface utilisateur.

Autres exemples:

Rebond du bouton Rebond de la diapositive Collection Springy Collection de sprint WWDC

Les étapes pour implémenter la dynamique UIKit sont toujours les mêmes:

  1. Créez un UIDynamicAnimatoret stockez-le dans une propriété solide
  2. Créez-en un ou plusieurs UIDynamicBehaviors. Chaque comportement doit avoir un ou plusieurs éléments, généralement une vue à animer.
  3. Assurez-vous que l'état initial des éléments utilisés dans UIDynamicBehaviorsest un état valide dans la UIDynamicAnimatorsimulation.
Memmons
la source
1
Salut Michael, merci beaucoup pour votre aide! Cela semble vraiment extrêmement facile à faire! Je l'ai essayé et cela fonctionne quand il touche le bas de la vue, mais cela ne fonctionne pas avec une autre vue - stackoverflow.com/questions/21895674 /... - J'adorerais si vous pouviez m'aider là-bas! :) Merci
user3127576
2
Un tutoriel MAGNIFIQUE MAIS vous n'utiliseriez qu'une seule ligne de code, usingSpringWithDamping, pour un rebond!
Fattie
2
Pouvez-vous partager un exemple de code pour l'animation de rebond Uitableview comme ci-dessus. J'essaye avec UITableview mais je ne sais pas par où commencer.
Dinesh
1
UIKit Dynamics est excellent lorsque vous traitez des cas d'exemple. Mais quand il s'agit de vraies tâches, vous voyez à quel point c'est brut et restreint. Un gros problème est le dépassement de UIDynamicItemBehavior(qui est en fait des propriétés, pas un comportement). Vous ne pouvez pas simplement utiliser différentes propriétés physiques dans différents comportements. Un autre cas est l'implémentation de limites en caoutchouc de type UIScrollView - c'est très compliqué. Je peux écrire encore plus mais le commentaire est trop court.
kelin
2
ajoutez le code complet s'il vous plaît. Votre code décrit comment créer UIDynamicAnimatoret les objets qui y sont associés, mais ne répond pas comment les utiliser
Vyachaslav Gerchicov
261

Une alternative plus simple à UIDynamicAnimator iOS 7 est Spring Animation (une nouvelle et puissante animation de bloc UIView), qui peut vous donner un bel effet de rebond avec amortissement et vitesse: Objectif C

[UIView animateWithDuration:duration
  delay:delay
  usingSpringWithDamping:damping
  initialSpringVelocity:velocity
  options:options animations:^{
    //Animations
    }
  completion:^(BOOL finished) {
    //Completion Block
}];

Rapide

UIView.animateWithDuration(duration,
     delay: delay,
     usingSpringWithDamping: damping,
     initialSpringVelocity: velocity,
     options: options,
     animations: {
            //Do all animations here
            }, completion: {
            //Code to run after animating
                (value: Bool) in
        })

Swift 4.0

UIView.animate(withDuration:duration,
     delay: delay,
     usingSpringWithDamping: damping,
     initialSpringVelocity: velocity,
     options: options,
     animations: {
            //Do all animations here
            }, completion: {
            //Code to run after animating
                (value: Bool) in
        })

usingSpringWithDamping 0.0 == très rebondissant. 1.0 le fait décélérer en douceur sans dépassement.

initialSpringVelocityest, à peu près, «distance souhaitée, divisée par les secondes souhaitées». 1.0 correspond à la distance totale d'animation parcourue en une seconde. Par exemple, la distance totale de l'animation est de 200 points et vous voulez que le début de l'animation corresponde à une vitesse de vue de 100 pt / s, utilisez une valeur de 0,5.

Un didacticiel plus détaillé et un exemple d'application peuvent être trouvés dans ce didacticiel . J'espère que c'est utile pour quelqu'un.

huong
la source
2
Voici un projet de démonstration que j'ai créé pour vous aider à obtenir une animation parfaite. Prendre plaisir! github.com/jstnheo/SpringDampingDemo
jstn
Vive ce projet de démonstration, mon pote. Aide vraiment à comprendre ces valeurs car elles sont assez obtuses. J'aurais aimé qu'Apple les ait clarifiés
kakubei
32

Voici un projet de démonstration que j'ai créé pour vous aider à obtenir une animation parfaite. Prendre plaisir!

SpringDampingDemo

entrez la description de l'image ici

jstn
la source
Vive ce projet de démonstration, mon pote. Aide vraiment à comprendre ces valeurs car elles sont assez obtuses. J'aurais aimé qu'Apple les ait clarifiés
kakubei
-1
- (IBAction)searchViewAction:(UIButton*)sender
{
  if(sender.tag == 0)
  {
    sender.tag = 1;

    CGRect optionsFrame2 = self.defaultTopView.frame;
    optionsFrame2.origin.x = -320;

    CGRect optionsFrame = self.searhTopView.frame;
    optionsFrame.origin.x = 320;
    self.searhTopView.frame = optionsFrame;

    [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:0 animations:^{

        CGRect optionsFrame = self.searhTopView.frame;

        optionsFrame.origin.x = 0;
        self.searhTopView.frame = optionsFrame;
        self.defaultTopView.frame = optionsFrame2;
    } completion:^(BOOL finished) {
    }];        
}
else
{
    sender.tag = 0;

    CGRect optionsFrame2 = self.defaultTopView.frame;
    optionsFrame2.origin.x = 0;

    CGRect optionsFrame = self.searhTopView.frame;
    optionsFrame.origin.x = 320;

    [UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:0 animations:^{

        CGRect optionsFrame = self.searhTopView.frame;

        optionsFrame.origin.x = 320;
        self.searhTopView.frame = optionsFrame;
        self.defaultTopView.frame = optionsFrame2;
    } completion:^(BOOL finished) {
    }];
}
}
Spydy
la source
1
Il n'y a aucune explication dans le code et aucun commentaire. Cela n'est pas utile
Lorenzo