Je lance ce code ...
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
CGAffineTransform settingsTransform = CGAffineTransformMakeTranslation(self.settingsView.frame.size.width, 0);
CGAffineTransform speedTransform = CGAffineTransformMakeTranslation(-self.speedView.frame.size.width, 0);
self.settingsView.transform = settingsTransform;
self.speedView.transform = speedTransform;
} completion:nil];
Mais lorsqu'il exécute les vues sautent la moitié de la transformation dans la direction opposée avant de glisser jusqu'à la moitié d'une position dans la bonne direction.
J'ai ralenti la durée de l'animation à 5 secondes, mais le saut initial est instantané et la moitié de la transformation dans la mauvaise direction.
Quand j'anime en utilisant ce code ...
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.settingsView.transform = CGAffineTransformIdentity;
self.speedView.transform = CGAffineTransformIdentity;
} completion:nil];
Cela fait exactement la même chose.
Le résultat est que le mouvement final correspond à la moitié de la transformation désirée puisqu'il saute la moitié de la transformation dans la mauvaise direction en premier.
Je ne peux vraiment pas comprendre pourquoi cela se produit?
Des idées.
::MODIFIER::
Éliminer une éventuelle ambiguïté.
Je n'essaie pas de faire en sorte que ces points de vue "rebondissent" là où ils se trouvent. Les vues que j'anime ressemblent au panneau de configuration situé au bord de l'écran. Lorsque l'utilisateur appuie sur "go", la vue glisse. Lorsque l'utilisateur appuie sur "stop", les panneaux reviennent dans la vue.
Au moins ils avaient l'habitude. Depuis l'activation de la mise en page automatique (dont j'ai besoin pour d'autres parties de l'application), je ne peux pas simplement changer le cadre des vues.
Vous pouvez voir cet effet en collant une vue dans un contrôleur de vue et un bouton permettant d'exécuter l'animation.
Merci
OK, après avoir visionné à nouveau les vidéos WWDC, ils affirment que l'une des premières choses à faire lorsque vous utilisez AutoLayout est de supprimer tous les appels à setFrame.
En raison de la complexité de l'écran, j'ai complètement supprimé la mise en page automatique et j'utilise maintenant l'emplacement du cadre pour déplacer la vue sur l'écran.
Merci
J'ai eu exactement le même problème, voici donc la solution que j'ai trouvée.
CGAffineTransform transform = CGAffineTransformMake(1, 0, 0, 1, translation.x, translation.y);
[UIView animateWithDuration:0.25 animations:^{
_assetImageView.transform = transform;
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
J'appelle donc [self.view layoutIfNeeded]; à l'intérieur du bloc animé. Sans cela, le problème est identique à celui que vous avez et saute la traduction en distance puis s’anime ensuite à la position correcte. J'appelle cela depuis un contrôleur de vue, alors self est une sous-classe de UIViewController. Dans votre cas, "self.view" peut ne pas exister, mais j'espère que vous en comprendrez l'idée.
Aucune des solutions ici ne fonctionnait pour moi ... Mon animation sautait toujours. (sauf quand c'était juste à la fin d'une autre animation, un indice).
Quelques détails:
La vue qui faisait cela avait une série d'échelles et se traduisait déjà dans la pile.
Solution:
Faire une animation par image clé, avec une première clé très courte qui réappliquerait la transformation que la dernière animation aurait dû définir.
UIView.animateKeyframesWithDuration(0.4, delay: 0.0, options: [.CalculationModeCubic], animations: { () -> Void in
//reset start point
UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.01, animations: { () -> Void in
self.element.transform = initialTransform
})
UIView.addKeyframeWithRelativeStartTime(0.01, relativeDuration: 0.99, animations: { () -> Void in
self.element.transform = finalTransform
})
}, completion: nil)
J'ai contacté le support technique Apple à propos de ce problème et obtenu cette réponse. Il s'agit donc d'un bogue.
iOS 8 présente actuellement un bogue connu dans les animations UIKit où Les animations de transformation obtiennent une valeur from from erronée (affectant principalement la position des objets animés, leur donnant l’impression de «sauter» inopinément au début d’une animation).
[...]
La solution de contournement jusqu'à ce qu'un correctif potentiel soit fourni doit être réduite à API de base d'animation pour coder vos animations.
Voici une version améliorée d'Andreas answer La différence essentielle est que vous ne pouvez spécifier qu'une seule image clé et obtenir moins de code
UIView.animateKeyframes(withDuration: animationDuration, delay: 0.0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 1.0, animations: {
animatedView.transform = newTransform
})
}, completion: nil)
Est-ce qu'une transformation a déjà été appliquée dans votre settingsView ou speedView avant que cette animation ait lieu?
Si les transformations de ces vues ne correspondent pas à la transformation d'identité (CGAffineTransformIdentity, autrement dit aucune transformation), vous ne pouvez pas accéder à leurs propriétés .frame.
Les propriétés de cadre d'UIViews ne sont pas valides lorsqu'une transformation leur est appliquée. Utilisez "bounds" à la place.
Puisque vous voulez que votre deuxième animation se produise à partir de l'état actuel de votre première animation (qu'elle soit terminée ou non), je vous recommande d'utiliser l'option UIViewAnimationOptionLayoutSubviews
lors du réglage de votre deuxième animation.
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionLayoutSubviews
animations:^{
self.settingsView.transform = CGAffineTransformIdentity;
self.speedView.transform = CGAffineTransformIdentity;
} completion:nil];
Voici un exemple du code utilisé pour tester en utilisant le modèle de contrôleur de vue simple:
myviewcontroller.m:
- (void)viewDidLoad
{
[super viewDidLoad];
self.animatedView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 160, 80)];
self.animatedView.backgroundColor = [UIColor yellowColor];
[UIView animateWithDuration:0.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionLayoutSubviews
animations:^{
CGAffineTransform settingsTransform = CGAffineTransformMakeTranslation(self.animatedView.frame.size.width, 0);
self.animatedView.transform = settingsTransform;
}
completion:nil];
self.buttonToTest = [UIButton buttonWithType:UIButtonTypeRoundedRect];
self.buttonToTest.frame = CGRectMake(90, 20, 80, 40);
[self.buttonToTest setTitle:@"Click Me!" forState:UIControlStateNormal];
[self.buttonToTest addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
// set-up view hierarchy
[self.view addSubview:self.buttonToTest];
[self.view addSubview: self.animatedView];
}
- (void) buttonClicked
{
[UIView animateWithDuration:.2
delay:0.0
options:UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionLayoutSubviews
animations:^{
self.animatedView.transform = CGAffineTransformIdentity;
}
completion:nil];
}
J'ai eu ce problème et résolu par:
J'espère que cela t'aides.