UILabel - étiquette de taille automatique pour s'adapter au texte?

144

Est-il possible de redimensionner automatiquement la zone / les limites UILabel pour s'adapter au texte contenu? (Je m'en fiche s'il finit par être plus grand que l'écran)

Donc, si un utilisateur entre "bonjour" ou "mon nom est vraiment long, je veux qu'il tienne dans cette case", il n'est jamais tronqué et l'étiquette est "élargie" en conséquence?

wayneh
la source
N'importe qui, s'il vous plaît, aidez-moi à fournir des codes SWIFT ..
Angel F Syrus

Réponses:

98

S'il vous plaît vérifier mon essentiel où j'ai créé une catégorie pour UILabelquelque chose de très similaire, ma catégorie permet d' UILabelétirer sa hauteur pour afficher tout le contenu: https://gist.github.com/1005520

Ou consultez cet article: https://stackoverflow.com/a/7242981/662605

Cela étirerait la hauteur, mais vous pouvez la changer facilement pour travailler dans l'autre sens et étirer la largeur avec quelque chose comme ceci, ce que je crois que vous voulez faire:

@implementation UILabel (dynamicSizeMeWidth)

- (void)resizeToStretch{
    float width = [self expectedWidth];
    CGRect newFrame = [self frame];
    newFrame.size.width = width;
    [self setFrame:newFrame];
}

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize maximumLabelSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX);

    CGSize expectedLabelSize = [[self text] sizeWithFont:[self font] 
                                            constrainedToSize:maximumLabelSize
                                            lineBreakMode:[self lineBreakMode]]; 
    return expectedLabelSize.width;
}

@end

Vous pouvez utiliser plus simplement la sizeToFitméthode disponible dans la UIViewclasse, mais définissez le nombre de lignes sur 1 pour être sûr.


Mise à jour iOS 6

Si vous utilisez la mise en page automatique, vous disposez d'une solution intégrée. En définissant le nombre de lignes sur 0, le cadre redimensionnera votre étiquette de manière appropriée (en ajoutant plus de hauteur) pour l'adapter à votre texte.


Mise à jour iOS 8

sizeWithFont:est obsolète alors utilisez sizeWithAttributes:plutôt:

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize expectedLabelSize = [[self text] sizeWithAttributes:@{NSFontAttributeName:self.font}];

    return expectedLabelSize.width;
}
Daniel
la source
8
En utilisant la méthode de mise en page automatique iOS 6, je me suis retrouvé avec une contrainte de hauteur sur mon étiquette dont je ne pouvais pas me débarrasser. La définition de la relation de la contrainte de hauteur sur «Supérieur ou égal» a permis à la hauteur d'augmenter.
Michael Luton
2
sizeWithFont: constrainedToSize: lineBreakMode: méthode dépréciée dans ios 7
Karan Alangat
1
UILabel ne se redimensionne pas lorsque le texte est inférieur / supérieur. J'utilise la mise en page automatique. J'ai essayé de créer UILabel mais ils sont créés à chaque fois que cellForRowAtIndex est initialisé. J'ai essayé beaucoup de choses. Rien ne fonctionne pour moi. Le fond de uilabel prend la même largeur. Aidez-moi !!!
coreDeviOS
@Daniel J'ai défini le nombre de lignes = 0, mais cela ne fonctionne pas. J'ai défini les contraintes de centre horizontal et vertical. Une chose supplémentaire que j'ai faite est de créer une sous-classe d'UILABEL et de l'utiliser pour cette étiquette
Jasmeet
Avec Autolayout, la solution la plus simple pour: (1) Définir les lignes sur 0, (2) Définir la contrainte de largeur sur "Supérieur ou égal" avec la constante 0, (3) Définir la contrainte de hauteur sur "Supérieur ou égal" avec la constante 0, ( 4) Alignez comme vous le feriez normalement, par exemple en centrant horizontalement et verticalement.
Erik van der Neut
76

En utilisant [label sizeToFit];, vous obtiendrez le même résultat avec la catégorie Daniels.

Bien que je recommande d'utiliser la mise en page automatique et de laisser l'étiquette se redimensionner en fonction des contraintes.

Guilherme Torres Castro
la source
3
Lors de l'utilisation de swift, j'ai dû l'exécuter sur le thread principal en utilisant dispatch_async (dispatch_get_main_queue (), {});
Zeezer
@Zeezer savez-vous pourquoi?
FurloSK
13
@FurloSK Toute modification sur l'interface utilisateur doit être effectuée dans le thread principal.
Guilherme Torres Castro
32

Si nous voulons que cela UILabeldiminue et s'agrandisse en fonction de la taille du texte, le storyboard avec mise en page automatique est la meilleure option. Voici les étapes pour y parvenir

Pas

  1. Mettez UILabel dans le contrôleur de vue et placez-le où vous le souhaitez. Également mis 0pour la numberOfLinespropriété de UILabel.

  2. Donnez-lui la contrainte de broche d'espacement Haut, Début et Fin.

entrez la description de l'image ici

  1. Maintenant, il donnera un avertissement, cliquez sur la flèche jaune.

entrez la description de l'image ici

  1. Cliquez sur Update Frameet cliquez sur Fix Misplacement. Maintenant, ce UILabel se rétrécira si le texte est moins et se développera si le texte est plus.
Yogesh Suthar
la source
1
Je n'ai pas testé la localisation, mais cela devrait aussi fonctionner pour cela.
Yogesh Suthar
2
Je ne pouvais pas faire fonctionner cela avec un projet existant jusqu'à ce que je décoché la case "Largeur préférée" "Explicite", alors tout a bien fonctionné.
zorro2b
25

Ce n'est pas aussi compliqué que certaines des autres réponses le font.

entrez la description de l'image ici

Épinglez les bords gauche et supérieur

Utilisez simplement la mise en page automatique pour ajouter des contraintes afin d'épingler les côtés gauche et supérieur de l'étiquette.

entrez la description de l'image ici

Après cela, il sera automatiquement redimensionné.

Remarques

  • N'ajoutez pas de contraintes pour la largeur et la hauteur. Les étiquettes ont une taille intrinsèque basée sur leur contenu textuel.
  • Merci à cette réponse pour votre aide.
  • Pas besoin de définir sizeToFitlors de l'utilisation de la mise en page automatique. Mon code complet pour l'exemple de projet est ici:

    import UIKit
    class ViewController: UIViewController {
    
        @IBOutlet weak var myLabel: UILabel!
    
        @IBAction func changeTextButtonTapped(sender: UIButton) {
            myLabel.text = "my name is really long i want it to fit in this box"
        }
    }
    
  • Si vous voulez que votre étiquette retourne à la ligne, définissez le nombre de lignes sur 0 dans IB et ajoutez myLabel.preferredMaxLayoutWidth = 150 // or whateverdu code. (J'ai également épinglé mon bouton au bas de l'étiquette pour qu'il se déplace vers le bas lorsque la hauteur de l'étiquette augmente.)

entrez la description de l'image ici

  • Si vous recherchez des étiquettes de dimensionnement dynamique à l'intérieur d'un, UITableViewCellconsultez cette réponse .

entrez la description de l'image ici

Suragch
la source
Bonjour, j'ai le libellé redimensionné mais je ne comprends pas comment redimensionner la hauteur de cellule. Pouvez-vous s'il vous plaît me faire savoir comment redimensionner la hauteur des cellules.
Vivek
@Vivek, tant que vous n'avez aucune contrainte définie sur la hauteur, il devrait se redimensionner automatiquement.
Suragch
Oui, mais comment c'est possible quand j'utilise une cellule personnalisée et que je mets 2 étiquettes dans sa cellule.
Vivek
@Vivek, désolé, j'ai mal lu votre question. Avez-vous déjà fait fonctionner une étiquette en parcourant cette réponse ?
Suragch
9

Utilisez [label sizeToFit];pour ajuster le texte dans UILabel

Gaurav Gilani
la source
5

J'ai créé quelques méthodes basées sur la réponse de Daniel ci-dessus.

-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text
{
    CGSize maximumLabelSize     = CGSizeMake(290, FLT_MAX);

    CGSize expectedLabelSize    = [text sizeWithFont:label.font
                                constrainedToSize:maximumLabelSize
                                    lineBreakMode:label.lineBreakMode];

    return expectedLabelSize.height;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label
{
    CGRect newFrame         = label.frame;
    newFrame.size.height    = [self heightForLabel:label withText:label.text];
    label.frame             = newFrame;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label withText:(NSString *)text
{
    label.text              = text;
    [self resizeHeightToFitForLabel:label];
}
Doug Baker
la source
5

Voici ce que je trouve fonctionne pour ma situation:

1) La hauteur du UILabel a une contrainte> = 0 en utilisant la disposition automatique. La largeur est fixe. 2) Affectez le texte à l'UILabel, qui a déjà une vue supervisée à ce stade (vous ne savez pas à quel point c'est vital). 3) Ensuite, faites:

    label.sizeToFit()
    label.layoutIfNeeded()

La hauteur de l'étiquette est maintenant réglée de manière appropriée.

Chris Prince
la source
3
@implementation UILabel (UILabel_Auto)

- (void)adjustHeight {

    if (self.text == nil) {
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, 0);
        return;
    }

    CGSize aSize = self.bounds.size;
    CGSize tmpSize = CGRectInfinite.size;
    tmpSize.width = aSize.width;

    tmpSize = [self.text sizeWithFont:self.font constrainedToSize:tmpSize];

    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, aSize.width, tmpSize.height);
}

@end

C'est la méthode des catégories. Vous devez d'abord définir le texte, puis appeler cette méthode pour ajuster la hauteur d'UILabel.

Kaijay Lu
la source
2

Vous pouvez dimensionner votre étiquette en fonction du texte et d'autres contrôles associés de deux manières:

  1. Pour iOS 7.0 et supérieur

    CGSize labelTextSize = [labelText boundingRectWithSize:CGSizeMake(labelsWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : labelFont
                                                        }
                                              context:nil].size;

avant iOS 7.0, cela pouvait être utilisé pour calculer la taille de l'étiquette

CGSize labelTextSize = [label.text sizeWithFont:label.font 
                            constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)  
                                lineBreakMode:NSLineBreakByWordWrapping];

// recadrage d'autres contrôles en fonction de labelTextHeight

CGFloat labelTextHeight = labelTextSize.height;
  1. Si vous ne souhaitez pas calculer la taille du texte de l'étiquette, vous pouvez utiliser -sizeToFit sur l'instance de UILabel comme-

    [label setNumberOfLines:0]; // for multiline label
    [label setText:@"label text to set"];
    [label sizeToFit];// call this to fit size of the label according to text

// après cela, vous pouvez obtenir le cadre d'étiquette pour recadrer d'autres contrôles connexes

vijeesh
la source
2
  1. Ajoutez les contraintes manquantes dans le storyboard.
  2. Sélectionnez UILabel dans le storyboard et définissez les attributs "Ligne" sur 0.
  3. Ref Sortez le UILabel sur Controller.h avec id: label
  4. Controller.m et ajoutez [label sizeToFit];viewDidLoad
user2941395
la source
1

J'ai eu d'énormes problèmes avec la mise en page automatique. Nous avons deux conteneurs à l'intérieur de la cellule de table. Le deuxième conteneur est redimensionné en fonction de la description de l'élément (0 à 1000 caractères) et la ligne doit être redimensionnée en fonction de ceux-ci.

L'ingrédient manquant était la contrainte inférieure pour la description.

J'ai changé la contrainte inférieure de l'élément dynamique de = 0 à > = 0 .

Bojan Tadic
la source
Cela m'a sauvé la vie. Si vous essayez de suivre: github.com/honghaoz/ ... c'est la bonne réponse.
Justin Fyles
0

Convient à chaque fois! :)

    name.text = @"Hi this the text I want to fit to"
    UIFont * font = 14.0f;
    CGSize size = [name.text sizeWithAttributes:@{NSFontAttributeName: font}];
    nameOfAssessment.frame = CGRectMake(400, 0, size.width, 44);
    nameOfAssessment.font = [UIFont systemFontOfSize:font];
HannahCarney
la source
0

vous pouvez afficher une sortie de ligne puis définir la propriété Line = 0 et afficher la sortie de plusieurs lignes, puis définir la propriété Line = 1 et plus

[self.yourLableName sizeToFit];
Dixit Akabari
la source
-1

Il y a aussi cette approche:

[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];
Dave Cole
la source
Ce n'est pas moi qui ai décliné cette réponse, mais je voulais juste souligner que je ne vois pas de changeTextWithAutoHeight:width:méthode UILabel. Pourriez-vous fournir un lien vers où dans la documentation UIKit cette méthode peut être trouvée.
Adil Hussain