web-dev-qa-db-fra.com

UILabel - étiquette de taille automatique pour adapter le texte?

Est-il possible de redimensionner automatiquement la zone/les limites UILabel en fonction du texte contenu? (Peu m'importe si sa taille est supérieure à celle de l'affichage)

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?

135
wayneh

S'il vous plaît consulter mon Gist où j'ai fait une catégorie pour UILabel pour quelque chose de très similaire, ma catégorie permet à une UILabel étirer sa hauteur pour afficher tout le contenu: https://Gist.github.com/1005520

Ou consultez ce post: https://stackoverflow.com/a/7242981/662605

Cela allongerait la hauteur, mais vous pouvez le changer facilement pour travailler dans l’autre sens et élargir la largeur avec quelque chose comme ça, c’est 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 plus simplement utiliser la méthode sizeToFit disponible dans la classe UIView, mais définir le nombre de lignes sur 1 pour qu'il soit sûr.


mise à jour iOS 6

Si vous utilisez AutoLayout, vous disposez d'une solution intégrée. En définissant le nombre de lignes sur 0, la structure redimensionnera votre étiquette de manière appropriée (en ajoutant plus de hauteur) pour s’ajuster à votre texte.


mise à jour iOS 8

sizeWithFont: est obsolète, utilisez donc sizeWithAttributes: à la place:

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

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

    return expectedLabelSize.width;
}
96
Daniel

Utiliser [label sizeToFit]; obtiendra le même résultat de la catégorie Daniels.

Bien que je recommande d’utiliser autolayout et de laisser l’étiquette se redimensionner en fonction de contraintes. 

70

Si nous voulons que UILabel soit réduit et développé en fonction de la taille du texte, le storyboard avec autolayout 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 voulez. Mettez également 0 pour la propriété numberOfLines de UILabel.

  2. Donnez-lui la contrainte de broche d'espace supérieur, principal et final.

enter image description here

  1. Maintenant, il va donner un avertissement, Cliquez sur la flèche jaune.

enter image description here

  1. Cliquez sur Update Frame et cliquez sur Fix Misplacement. Maintenant, ce UILabel sera réduit si le texte est inférieur et élargi si le texte est supérieur.
30
Yogesh Suthar

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

 enter image description here

Épingler les bords gauche et supérieur

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

 enter image description here

Après cela, il sera automatiquement redimensionné.

Remarques

  • N'ajoutez pas de contraintes pour la largeur et la hauteur. Les étiquettes ont une taille intrinsic basée sur leur contenu textuel.
  • Merci à cette réponse pour l'aide avec ceci.
  • Pas besoin de définir sizeToFit lors de l'utilisation de la disposition 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 souhaitez que votre étiquette retourne à la ligne, définissez le nombre de lignes sur 0 dans IB et ajoutez myLabel.preferredMaxLayoutWidth = 150 // or whatever dans le code. (J'ai également épinglé mon bouton au bas de l'étiquette pour qu'il descende lorsque la hauteur de l'étiquette augmente.)

 enter image description here

  • Si vous recherchez des étiquettes de taille dynamique dans une UITableViewCell, voyez cette réponse .

 enter image description here

20
Suragch

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

9
Gaurav Gilani

J'ai créé des 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];
}
5
Doug Baker
@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 de la catégorie. Vous devez d'abord définir le texte avant d'appeler cette méthode pour ajuster la hauteur de UILabel.

3
Kaijay Lu

Vous pouvez redimensionner 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];

// recadrer d'autres contrôles basés sur labelTextHeight

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

    [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 de l'étiquette pour recadrer d'autres contrôles connexes

2
vijeesh

Voici ce que je trouve fonctionne dans ma situation:

1) La hauteur de UILabel a une contrainte> = 0 utilisant autolayout. La largeur est fixée . 2) Assignez le texte dans le UILabel, qui a déjà un survol à ce moment-là (vous ne savez pas à quel point cela est vital) . 3) Ensuite, faites:

    label.sizeToFit()
    label.layoutIfNeeded()

La hauteur de l'étiquette est maintenant définie correctement.

2
Chris Prince
  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 Outlet le UILabel à Controller.h avec id: label
  4. Controller.m et ajouter [label sizeToFit]; dans viewDidLoad
2
user2941395

J'ai eu un énorme problème avec la mise en page automatique. Nous avons deux conteneurs dans 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 ces éléments 

L'ingrédient manquant était la contrainte du bas pour la description. 

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

1
Bojan Tadic

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

[self.yourLableName sizeToFit];
0
Dixit Akabari

Convient à tout moment! :)

    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];
0