29 votes

Gérer les différences d'animation de contrainte AutoLayout dans iOS 10?

J'ai remarqué que dans iOS 10 Beta 5 (sur le point d'essayer la Bêta 6), mise en page automatique contrainte animation se comporte un peu différemment.

Par exemple, cette approche ne fonctionne pas de la même façon que dans les précédentes versions du logiciel iOS:

[view addConstraints:@[constraints...]];

[view setNeedsUpdateConstraints];
[view layoutIfNeeded];

[UIView animateWithDuration:...
{
    /* adjust constraint here... */
    [view layoutIfNeeded]; // Only the adjusted constraints since previous layoutIfNeeded() call should animate change with duration.

} completion:{ ... }];

... Lors de mes tests, les contraintes initialement ajouté avec addConstraints() va également animer dans iOS 10 avec le UIView animateWithDuration() bloc... qui est à l'origine de certains funky/comportement indésirable jusqu'à présent.

Par exemple, la définition de la gauche/droite contraintes dans le tableau (mais les contraintes verticales dans le bloc) les causes de la totalité de la vue d'animer sur l'écran en diagonale avec cette approche... ce qui est totalement erroné.

Personne ne sait comment le faire correctement pour iOS 9 (et ci-dessous), ainsi que 10?

90voto

beebcon Points 1401

Essayez d'appeler layoutIfNeeded sur le point de vue de l'superview, au lieu de la vue elle-même.

--

J'ai eu un problème similaire, mon avis était censé animer à partir du haut à 0 hauteur, vers le bas pour a > 0 hauteur (c (0, 0, 320, 0) à (0, 0, 320, 44)).

En utilisant Xcode avec iOS 8 à 10, le comportement de l'animation était très différente. Au lieu d'animer à la baisse depuis le sommet, la vue s'anime en haut & en bas de la verticale du centre de l'image de destination.

J'ai corrigé cela, au lieu de l'appeler layoutIfNeeded sur la vue elle-même, en l'appelant sur le point de vue de l'superview. En quelque sorte, le comportement a été restauré.

Espérons que cela aide!


Commentaire par @Ramiro:

Selon la documentation, layoutIfNeeded énonce les sous-vues (mais n'a pas de contempler la vue actuelle elle-même). Donc, pour mettre à jour la vue actuelle de vous exposer, vous devez appeler layoutIfNeeded de la super vue.

2voto

Rizwan Shaikh Points 150

Dans la méthode ci-dessous:

 [super viewDidLoad];
 

Écrivez cette ligne:

  [self.view layoutIfNeeded];
 

0voto

ingconti Points 405

J'ai fait un petit test en changeant H et V d'une petite vue rouge:

 self.red_POS_H = NSLayoutConstraint.constraints(withVisualFormat: "H:|-90-[redView]", options: defaultOptions, metrics: nil, views: viewsDictionary)


self.red_POS_V = NSLayoutConstraint.constraints(withVisualFormat: "V:|-30-[redView]", options: defaultOptions, metrics: nil, views: viewsDictionary)

self.view.addConstraints(self.red_POS_V!)
self.view.addConstraints(self.red_POS_H!)
 

et l'animation:

         // we hope is only one:
        let currV = self.red_POS_V![0]
        let currH = self.red_POS_H![0]


        UIView.animate(withDuration: 3) { 
            // Make all constraint changes here

            currV.constant = 100
            currH.constant = 300

            self.view.layoutIfNeeded() // Forces the layout of the subtree animation block and then captures all of the frame changes
        }
 

la vue rouge s'est déplacée correctement, si vous commentez une seule ligne dans l'animation, cela fonctionne, horizontalement ou verticalement.

Petit projet disponible, si vous en avez besoin.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X