AutoLayout: UIView dans UIView a un cadre incorrect

Je travaille avec AutoLayout dans Storyboard, et tout semblait aller bien. Cependant, quand je mets un UIView dans un autre et que j'applique toutes les contraintes que je veux à la fois au conteneur et à ses enfants, je remarque que le cadre est incorrect dans viewDidLayoutSubviews: Plutôt que d'être le cadre que je m'attendrais à calculer count tenu de mes contraintes, c'est un cadre dégoûtant de grande taille (bien qu'à la bonne origine). Par exemple, plutôt qu'une trame de {{26, 10}, {444, 10}}, j'obtiens quelque chose comme {{0, 0}, {320, 568}} .

Curieusement, cela n'arrive à l'enfant UIView que lorsque je le situe dans un autre UIView qui a des contraintes qui lui sont appliquées par rapport à sa superview (qui est la vue du controller de vue). Comme je suis sous l'printing que je peux m'attendre à ce que mes vues soient correctement présentées selon mes contraintes dans la méthode viewDidLayoutSubviews: je suis confus quant à la raison pour laquelle cela se produit.

Est-ce que je fais des suppositions incorrectes? J'apprécierais que quelqu'un puisse m'aider à me diriger dans la bonne direction. Merci!

Remarque: Ce problème est complètement résolu si je fais ma configuration dépendante du cadre correct dans viewDidAppear: mais c'est une solution de contournement quelque peu insatisfaisante pour moi.

Les changements de layout automatique des limites ne sont pas nécessairement terminés dans -viewDidLayoutSubviews . Comme mis dans "Advance Auto Layout Toolbox" :

La layout basée sur les contraintes est un process itératif. Le passage de layout peut apporter des modifications aux contraintes en fonction de la solution de layout précédente, ce qui triggers à nouveau la mise à jour des contraintes après un autre passage de layout.

La documentation pour -viewDidLayoutSubviews note avec emphase dans l'original :

Cependant, cette méthode appelée n'indique pas que les dispositions individuelles des sous-vues de la vue ont été ajustées.

Les itérations de layout et de contrainte dans les sous-vues peuvent donc continuer à ajuster leurs trames, mais si les limites d'une vue de ViewController ne changent pas, ses -viewWillLayoutSubviews ne seront pas appelées.

Puisque vous dites que votre configuration dépend du cadre, vous avez quelques options.

  1. Faites votre installation dans -viewWillAppear . Mieux que -viewDidAppear , et puisque vous avez vraiment besoin que tout soit fait après toute la layout si elle est terminée mais avant qu'elle n'apparaisse à l'écran, c'est une raison légitime pour laquelle la méthode est là. Le cas échéant, vous pouvez essayer d'appeler -isMovingToParentViewController comme décrit dans la section Détermination de l'apparence d'une vue modifiée .
  2. Appelez -layoutIfNeeded sur les vues dont vous avez besoin pour avoir les valeurs correctes où vous en avez besoin. Parce que cela fait le travail de layout c'est cher, et cela pourrait conduire à un travail répétitif en cours ou même une boucle infinie si elle est déclenchée au cours de son propre process de layout. Mais c'est utile si vous avez besoin de synchroniser certaines valeurs avec Auto Layout pour les utiliser.

Si cela ne fonctionne pas, laissez-nous savoir, cela pourrait avoir à voir avec la nature des contraintes elles-mêmes ou quelque chose d'autre. Les itérations de layout automatique peuvent être difficiles à synchroniser. Bonne chance.