web-dev-qa-db-fra.com

redimensionner les super vues après la modification dynamique des vues secondaires à l'aide de autolayout

Je ne peux pas pour l'amour de dieu le coup de cette superview redimensionnant.

J'ai un UIView *superview Avec 4 UILabels. 2 fonctionnent comme en-tête pour les 2 autres.

Le contenu des 4 éléments est dynamique et provient de la base de données.

SizeToFit vs SizeThatFits:(CGSize) vs UIView systemLayoutSizeFittingSize:, en passant soit UILayoutFittingCompressedSize ou UILayoutFittingExpandedSize.

J'utilise autolayout par programmation et j'ai défini la hauteur de la vue supérieure ou égale à un nombre factice.

où et comment puis-je utiliser ces SizeToFit vs sizeThatFits:(CGSize) vs UIView systemLayoutSizeFittingSize:, en passant soit UILayoutFittingCompressedSize ou UILayoutFittingExpandedSize. J'ai lu beaucoup de conseils ici sur la pile, mais rien avec rien.

DO je dois recalculer les contraintes pour la superview quelque part spécifique. Maby a défini la hauteur sur "@ property" dans sa classe de contrôleur et l'a supprimée et lue? J'ai essayé de tout mettre partout et ensuite. J'ai toujours le même résultat final avec la hauteur factice et le texte flottant à l'extérieur. Même après avoir défini clipsToBound sur la sous-vue.

Je me gratte les cheveux de .. aide

81
Pedroinpeace

Si vous utilisez la mise en page automatique, voici ce que vous devez faire:

  1. Assurez-vous de ne pas ajouter de contraintes de largeur et/ou de hauteur fixes à vos sous-vues (en fonction de la ou des dimensions que vous souhaitez dimensionner de manière dynamique). L'idée est de laisser la taille du contenu intrinsèque de chaque sous-vue déterminer la hauteur de la sous-vue. UILabels est livré avec 4 contraintes implicites automatiques qui tenteront (avec une priorité inférieure à la priorité requise) de conserver le cadre de l'étiquette à la taille exacte requise pour contenir tout le texte à l'intérieur.

  2. Assurez-vous que les bords de chaque étiquette sont reliés de manière rigide (avec les contraintes de priorité requises) aux bords les uns des autres et à leur vue d'ensemble. Vous voulez vous assurer que si vous imaginez que l'une des étiquettes grossisse, cela obligerait les autres étiquettes à lui laisser la place et surtout à forcer le développement de Superview.

  3. Ajoutez uniquement des contraintes à la vue d'ensemble pour définir sa position et non sa taille (du moins, pas pour la ou les dimensions que vous souhaitez dimensionner de manière dynamique). N'oubliez pas que si vous définissez correctement les contraintes internes, sa taille sera déterminée par la taille de toutes les sous-vues, car ses bords sont connectés aux siens d'une manière ou d'une autre.

C'est ça. Vous n'avez pas besoin d'appeler sizeToFit ou systemLayoutSizeFittingSize: Pour que cela fonctionne, il suffit de charger vos vues et de définir le texte, ce qui devrait être le cas. Le moteur de présentation du système effectuera les calculs pour vous permettre de résoudre vos contraintes. (Dans le meilleur des cas, vous devrez peut-être appeler setNeedsLayout dans la vue d'ensemble ... mais cela ne devrait pas être nécessaire.)

102
smileyborg

Utiliser les vues de conteneur

Dans l'exemple suivant, j'ai une image 30x30, et le UILabel est plus petit que la vue contenant le texte avec espace réservé. J'avais besoin que la vue contenant soit au moins aussi grande que l'image, mais elle devait s'agrandir pour contenir un texte multiligne.

En format visuel, le conteneur interne ressemble à ceci:

H:|-(15.0)-[image(30.0)]-(15.0)-[label]-(15.0)-|
V:|[image(30.0)]|
V:|[label(>=30.0)]|

Ensuite, définissez la vue contenant pour qu'elle corresponde à la hauteur de l'étiquette. Maintenant, la vue contenant chevauchera la taille de l'étiquette.

Comme @smileyborg l'a souligné dans sa réponse, le fait de relier le contenu de manière rigide à la vue d'ensemble informe le moteur de mise en page que la simple vue de conteneur doit entraîner sa croissance.

Rectangle d'alignement jaune

Si vous voulez les rectangles d’alignement jaunes, ajoutez -UIViewShowAlignmentRects YES dans la liste des arguments d'exécution de votre schéma.

UILabel that is multi-line

24

Cela a été considérablement simplifié avec l'introduction de Stack Views dans iOS 9. Utilisez une vue de pile dans votre vue pour contenir tout votre contenu redimensionné, puis appelez simplement

view.setNeedsUpdateConstraints()
view.updateConstraintsIfNeeded()
view.setNeedsLayout()
view.layoutIfNeeded()

après avoir changé votre contenu. Ensuite, vous pouvez obtenir votre nouvelle taille en appelant

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

si vous avez besoin de calculer la taille exacte requise pour une vue.

5
Jacob Ruth

Cela fait presque suite à la réponse de @smileyborg et vient avec un exemple concret.

enter image description here

Ne décrira pas toutes les contraintes, mais celles liées au calcul de la hauteur d'objets UI.

  1. [Label] Les étiquettes ne doivent pas avoir de contrainte fixe height. Dans ce cas, AutoLayout ne redimensionnera pas les étiquettes pour les adapter au texte, la définition des contraintes de bord est donc la clé. (flèches vertes)
  2. [Sous-vue] Les étapes 1 et 3 sont très faciles à suivre, mais cette étape peut être mal comprise. Comme dans le cas des étiquettes, les contraintes de sous-vues ne doivent pas être définies sur height. Toutes les sous-vues doivent avoir la contrainte top définie, ignorant la contrainte bottom, ce qui peut vous faire penser qu'elle déclenchera une exception de contrainte non satisfaite au moment de l'exécution, mais ne le fera pas si vous définissez bottom contrainte. pour la dernière sous-vue. Manquer à cela fera sauter la mise en page. (flèches rouges)

  3. [Aperçu] Définissez toutes les contraintes comme vous le souhaitez, mais faites très attention à la contrainte height. Attribuez-lui une valeur aléatoire, mais rendez-la facultative. AutoLayout définira la hauteur avec précision pour s'adapter aux sous-vues. (flèches bleues!

Cela fonctionne parfaitement, il n'est pas nécessaire d'appeler d'autres méthodes de mise à jour de la disposition du système.

4
tesla