Comment suis-je censé configurer par programme (et dans quelle méthode) un UILabel dont la hauteur dépend de son texte? J'ai essayé de le configurer en utilisant une combinaison de Storyboard et de code, mais en vain. Tout le monde recommande sizeToFit
lors du réglage lineBreakMode
et numberOfLines
. Cependant, peu importe si je mets ce code dans viewDidLoad:
, viewDidAppear:
ou viewDidLayoutSubviews
je ne peux pas le faire au travail. Soit je fais la boîte trop petite pour du texte long et elle ne grossit pas, soit je la fais trop grande et elle ne rétrécit pas.
ios
ios6
uilabel
autolayout
circuitlego
la source
la source
label.sizeToFit()
dans Xcode / viewController, les contraintes étaient suffisantes. ne créait pas l'étiquette dans Playground . Jusqu'à présent, la seule façon dont je l'ai trouvé pour fonctionner dans Playground est de le fairelabel.sizeToFit()
Réponses:
Veuillez noter que dans la plupart des cas, la solution de Matt fonctionne comme prévu. Mais si cela ne fonctionne pas pour vous, veuillez lire la suite.
Pour que votre étiquette redimensionne automatiquement la hauteur, vous devez procéder comme suit:
Par exemple:
Utilisation d'Interface Builder
Définissez quatre contraintes. La contrainte de hauteur est obligatoire.
Accédez ensuite à l'inspecteur des attributs de l'étiquette et définissez le nombre de lignes sur 0.
Accédez à l'inspecteur de taille de l'étiquette et augmentez ContentHuggingPriority vertical et ContentCompressionResistancePriority vertical.
Sélectionnez et modifiez la contrainte de hauteur.
Et diminuez la priorité des contraintes de hauteur.
Prendre plaisir. :)
la source
preferredMaxLayoutWidth
ou épinglez la largeur de l'étiquette (ou ses côtés droit et gauche). C'est tout! Il se développera alors automatiquement et se rétrécira verticalement pour s'adapter à son contenu.Dans iOS 6, en utilisant la mise en page automatique, si les côtés (ou la largeur) et le dessus d'un UILabel sont épinglés, il se développera automatiquement et se rétrécira verticalement pour s'adapter à son contenu, sans code du tout et sans gâcher sa résistance à la compression ou autre. C'est très simple.
Dans les cas plus complexes, définissez simplement les étiquettes
preferredMaxLayoutWidth
.Dans tous les cas, la bonne chose se produit automatiquement.
la source
label.sizeToFit()
Bien que la question se déclare par programme, ayant rencontré le même problème et préférant travailler dans Interface Builder, j'ai pensé qu'il pourrait être utile d'ajouter aux réponses existantes avec une solution Interface Builder.
La première chose est d'oublier
sizeToFit
. La disposition automatique gérera cela en votre nom en fonction de la taille du contenu intrinsèque.Le problème est donc de savoir comment obtenir une étiquette pour l'adapter à son contenu avec la mise en page automatique? Plus précisément - parce que la question le mentionne - la hauteur. Notez que les mêmes principes s'appliquent à la largeur.
Commençons donc par un exemple d'UILabel dont la hauteur est fixée à 41 px de haut:
Comme vous pouvez le voir dans la capture d'écran ci-dessus,
"This is my text"
a un rembourrage au-dessus et en dessous. C'est un remplissage entre la hauteur de l'UILabel et son contenu, le texte.Si nous exécutons l'application dans le simulateur, bien sûr, nous voyons la même chose:
Maintenant, sélectionnons UILabel dans Interface Builder et examinons les paramètres par défaut dans l'inspecteur de taille:
Notez la contrainte mise en évidence ci-dessus. Telle est la priorité du contenu . Comme le décrit Erica Sadun dans l'excellent iOS Auto Layout Demystified , c'est:
Pour nous, avec l'UILabel, le contenu principal est le texte.
Nous arrivons ici au cœur de ce scénario de base. Nous avons donné à notre étiquette de texte deux contraintes. Ils sont en conflit. On dit "la hauteur doit être égale à 41 pixels de haut" . L'autre dit "embrassez la vue sur son contenu afin que nous n'ayons pas de remplissage supplémentaire" . Dans notre cas, étreignez la vue sur son texte pour ne pas avoir de remplissage supplémentaire.
Maintenant, avec la mise en page automatique, avec deux instructions différentes qui disent faire des choses différentes, le moteur d'exécution doit choisir l'une ou l'autre. Il ne peut pas faire les deux. Le UILabel ne peut pas avoir à la fois 41 pixels de haut et n'a pas de remplissage.
La façon dont cela est résolu est de spécifier la priorité. Une instruction doit avoir une priorité plus élevée que l'autre. Si les deux instructions disent des choses différentes et ont la même priorité, une exception se produira.
Alors, essayons. Ma contrainte de hauteur a une priorité de 1000 , ce qui est obligatoire . La hauteur de contention du contenu est de 250 , ce qui est faible . Que se passe-t-il si nous réduisons la priorité de la contrainte de hauteur à 249 ?
Maintenant, nous pouvons voir la magie commencer à se produire. Essayons dans la sim:
Impressionnant! Étreinte du contenu réalisée. Uniquement parce que la priorité de hauteur 249 est inférieure à la priorité de contenu 250 . Fondamentalement, je dis "la hauteur que je spécifie ici est moins importante que ce que j'ai spécifié pour l'étreinte du contenu" . Ainsi, le contenu étreignant gagne.
En bout de ligne, faire en sorte que l'étiquette s'adapte au texte peut être aussi simple que de spécifier la contrainte de hauteur ou de largeur et de corriger la définition de cette priorité en association avec la contrainte de priorité de contournement du contenu de cet axe.
Je vais laisser faire l'équivalent pour la largeur comme exercice pour le lecteur!
la source
Remarqué dans IOS7 sizeToFit ne fonctionnait pas non plus - peut-être que la solution peut vous aider aussi
la source
layoutIfNeeded
quand vous en avez besoinsetNeedsUpdateConstraints
. Mais la situation pourrait être un peu différente.Une autre option pour garantir que la valeur favoriteMaxLayoutWidth de l'étiquette est synchronisée avec la largeur de l'étiquette:
la source
Je pense que je devrais contribuer car il m'a fallu un certain temps pour trouver la bonne solution:
Fondamentalement, ce qui se passe est que vous dites à votre UILabel que même s'il a une contrainte de hauteur fixe, il peut faire casser la contrainte pour se rendre plus petit afin de serrer le contenu (si vous avez une seule ligne par exemple), mais il ne peut pas briser la contrainte pour l'agrandir.
la source
Dans mon cas, je créais une sous-classe UIView qui contenait un UILabel (de longueur inconnue). Dans iOS7, le code était simple: définissez les contraintes, ne vous inquiétez pas de l'étreinte du contenu ou de la résistance à la compression, et tout fonctionnait comme prévu.
Mais dans iOS6, l'UILabel était toujours tronqué sur une seule ligne. Aucune des réponses ci-dessus n'a fonctionné pour moi. Les paramètres de contention du contenu et de résistance à la compression ont été ignorés. La seule solution qui empêchait l'écrêtage était d'inclure un PreferredMaxLayoutWidth sur l'étiquette. Mais je ne savais pas sur quoi définir la largeur préférée, car la taille de sa vue parente était inconnue (en effet, elle serait définie par le contenu).
J'ai enfin trouvé la solution ici . Comme je travaillais sur une vue personnalisée, je pouvais simplement ajouter la méthode suivante pour définir la largeur de mise en page préférée une fois que les contraintes avaient été calculées une fois, puis les recalculer:
la source
J'ai ajouté par
UILabel
programme et dans mon cas, c'était suffisant:la source
J'ai résolu avec xCode6 en mettant "Largeur préférée" sur Automatique et épingler le haut de l'étiquette, le début et la fin
la source
la source
J'ai également rencontré ce problème avec une sous-classe UIView qui contient un UILabel comme si ses éléments internes. Même avec la mise en page automatique et en essayant toutes les solutions recommandées, l'étiquette ne serrait tout simplement pas sa hauteur au texte. Dans mon cas, je veux que l'étiquette ne soit qu'une ligne.
Quoi qu'il en soit, ce qui a fonctionné pour moi était d'ajouter une contrainte de hauteur requise pour le UILabel et de le définir manuellement à la hauteur correcte lorsque intrinsicContentSize est appelé. Si vous n'avez pas le UILabel contenu dans un autre UIView, vous pouvez essayer de sous-classer UILabel et fournir une implémentation similaire en définissant d'abord la contrainte de hauteur, puis en retournant
[super instrinsicContentSize]; au lieu de [self.containerview intrinsiceContentSize]; comme je le fais ci-dessous, ce qui est spécifique à ma sous-classe UIView.
Fonctionne parfaitement maintenant sur iOS 7 et iOS 8.
la source
intrinsicContentSize
. Le moteur d'exécution doit être en mesure de calculer cela en fonction de vos contraintes correctement configurées.Une solution qui a fonctionné pour moi; Si votre UILabel a une largeur fixe, changez la contrainte de
constant =
àconstant <=
dans votre fichier d'interfacela source
Dans mon cas, lors de l'utilisation des étiquettes dans un UITableViewCell, l'étiquette à redimensionnerait mais la hauteur dépasserait la hauteur de la cellule du tableau. C'est ce qui a fonctionné pour moi. Je l'ai fait selon Max MacLeod, puis je me suis assuré que la hauteur de cellule était définie sur UITableViewAutomaticDimension.
Vous pouvez ajouter ceci dans votre init ou awakeFromNib,
Dans le storyboard, sélectionnez la cellule, ouvrez l'inspecteur de taille et assurez-vous que la hauteur de ligne est définie sur "Par défaut" en cochant la case "Personnalisé".
Il existe un problème dans la version 8.0 qui nécessite également qu'il soit défini dans le code.
la source