web-dev-qa-db-fra.com

Testez si une UIView est au milieu de l'animation

Existe-t-il un moyen de savoir si une UIView est au milieu d'une animation? Lorsque j'imprime l'objet de vue pendant qu'il se déplace, je remarque qu'il y a une entrée "animations":

search bar should end editing: <UISearchBar: 0x2e6240; frame = (0 0; 320 88); text = ''; autoresize = W+BM; animations = { position=<CABasicAnimation: 0x6a69c40>; bounds=<CABasicAnimation: 0x6a6d4d0>; }; layer = <CALayer: 0x2e6e00>>

Lorsque l'animation s'est arrêtée et que j'imprime la vue, l'entrée "animations" a disparu:

search bar should end editing: <UISearchBar: 0x2e6240; frame = (0 0; 320 88); text = ''; autoresize = W+BM; layer = <CALayer: 0x2e6e00>>
45
prostock

Une UIView a une couche ( CALayer ). Vous pouvez lui envoyer animationKeys qui vous donnera un tableau de clés identifiant les animations attachées au calque. Je suppose que s'il y a des entrées, les animations sont en cours d'exécution. Si vous voulez creuser encore plus, jetez un œil au protocole CAMediaTiming que CALayer adopte. Il fait plus d'informations sur l'animation actuelle.

39
Nick Weaver

Les animations sont en fait attachées à la classe Core Animation CALayer sous-jacente

Je pense donc que vous pouvez simplement vérifier myView.layer.animationKeys

25
Vincent Guerci

méthode iOS 9+, fonctionne même lorsque layer.animationKeys ne contient aucune clé:

let isInTheMiddleOfAnimation = UIView.inheritedAnimationDuration > 0

De la documentation:

Cette méthode ne renvoie une valeur non nulle que si elle est appelée dans un bloc d'animation UIView.

10
deej

Je ne suis pas sûr du contexte de la question mais j'avais essayé de savoir si une vue s'animait avant de commencer une deuxième animation pour éviter de sauter. Cependant, il existe une option d'animation UIView UIViewAnimationOptionBeginFromCurrentState qui combinera les animations si nécessaire pour donner une apparence fluide. Éliminant ainsi mon besoin de savoir si la vue était animée.

8
Ryan Poolos

Il y a un problème avec l'astuce animationKeys.

Parfois, il peut y avoir quelques animationsKeys qui restent après la fin d'une animation.

Cela signifie qu'un calque non animé peut renvoyer un ensemble de clés d'animation même s'il n'est pas réellement animé.

Vous pouvez vous assurer que les clés animationKeys sont automatiquement supprimées en définissant la propriété removeOnCompletion d'une animation sur YES.

par exemple.

CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"aPath"];
animation.removedOnCompletion = YES;

Si vous le faites pour toutes les animations que vous appliquez à votre calque, cela garantira que lorsque le calque ne s'anime pas, aucune clé d'animation n'est présente.

5
C4 - Travis

Certains d'entre eux n'ont pas fonctionné pour moi. La raison en est que ces animations sont asynchrones.

J'ai défini une propriété

@property BOOL viewIsAnimating;

Et dans mon animation

[UIView animateWithDuration:0.25
                 animations:^{
                     viewIsAnimating = YES;
                 } completion:^(BOOL finished) {
                     if (finished) {
                         viewIsAnimating = NO;
                     }
                 }];
3
MendyK

Réf à la question: position centrale UIView pendant l'animation

Je compare le cadre de la vue et le cadre layer.presentation () ?. pour vérifier qu'il est animé. Si leftView est sur le point de terminer, le cadre leftView.layer.presentation () ?. n'est pas égal à son cadre:

if self.leftView.layer.presentation()?.frame == self.leftView.frame {
   // the animation finished
} else {
   // the animation on the way
}

Mais cette méthode peut ne pas fonctionner si la vue se déplace vers la position finale pendant l'animation. Une vérification plus approfondie de l'état peut être nécessaire.

1
Bill Chan

Vous pouvez utiliser la propriété de couche d'un UIView. CALayer a une propriété appelée clés d'animation, vous pouvez vérifier son nombre s'il est supérieur à 0.

if (view.layer.animationKeys.count) {

  // Animating

}else {

// No

}

Dans la documentation:

-(nullable NSArray<NSString *> *)animationKeys;

Renvoie un tableau contenant les clés de toutes les animations actuellement * attachées au récepteur. L'ordre du tableau correspond à l'ordre * dans lequel les animations seront appliquées.

1
varunrathi28

Vous pouvez interroger la couche de présentation comme suggéré ici Ma couche de présentation ne correspond pas à ma couche modèle même si je n'ai pas d'animations

0
HeikoG