web-dev-qa-db-fra.com

Gestion des différences d’animation de contrainte AutoLayout dans iOS 10?

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

Par exemple, cette approche ne fonctionne pas comme dans les versions précédentes d'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ées avec addConstraints() vont aussi s'animer sous iOS 10 avec le bloc UIView animateWithDuration() ..., ce qui provoque un comportement funky/indésirable jusqu'à présent.

Par exemple, définir les contraintes gauche/droite dans le tableau (mais les contraintes verticales dans le bloc) provoque l'animation diagonale de la vue sur l'écran} avec cette approche ... totalement incorrecte.

Est-ce que quelqu'un sait comment faire cela correctement pour iOS 9 (et inférieur), ainsi que pour 10?

29
Ben Guild

Essayez d'appeler layoutIfNeeded dans la vue supérieure, au lieu de la vue elle-même.

-

J'avais un problème similaire, ma vue était supposée s'animer du haut à une hauteur de 0, vers le bas jusqu'à une hauteur de> 0 (c'est-à-dire (0, 0, 320, 0) à (0, 0, 320, 44)).

En utilisant Xcode 8 avec iOS 10, le comportement de l'animation était très différent. Au lieu d’animer de haut en bas, la vue s’anime de haut en bas à partir du centre vertical du cadre de destination.

J'ai résolu ce problème en, au lieu d'appeler layoutIfNeeded sur la vue elle-même, en l'appelant dans le super aperçu de la vue. D'une certaine manière, le comportement a été restauré.

J'espère que ça aide!


Commentaire utile de @Ramiro:

Selon la documentation, layoutIfNeeded affiche les sous-vues (mais ne considère pas la vue actuelle elle-même). Ainsi, pour mettre à jour la disposition de la vue actuelle, vous devez appeler layoutIfNeeded à partir de la super vue.

90
beebcon

Dans la méthode ci-dessous:

[super viewDidLoad];

Écrivez cette ligne:

 [self.view layoutIfNeeded];
2
Rizwan Shaikh

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'a animé:

        // 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 une animation, cela fonctionne, horizontalement ou verticalement.

Petit projet disponible, si vous en avez besoin.

0
ingconti