Comment calculer la largeur UILabel en fonction de la longueur du texte?

142

Je veux afficher une image à côté d'un UILabel, cependant UILabel a une longueur de texte variable, donc je ne sais pas où placer l'image. Comment puis-je accomplir cela?

Sheehan Alam
la source

Réponses:

191
CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font 
                        constrainedToSize:maximumLabelSize 
                        lineBreakMode:yourLabel.lineBreakMode]; 

À quoi sert - [NSString sizeWithFont: forWidth: lineBreakMode:]?

cette question pourrait avoir votre réponse, cela a fonctionné pour moi.


Pour 2014, j'ai édité dans cette nouvelle version, basée sur le commentaire ultra-pratique de Norbert ci-dessous! Cela fait tout. À votre santé

// yourLabel is your UILabel.

float widthIs = 
 [self.yourLabel.text
  boundingRectWithSize:self.yourLabel.frame.size                                           
  options:NSStringDrawingUsesLineFragmentOrigin
  attributes:@{ NSFontAttributeName:self.yourLabel.font }
  context:nil]
   .size.width;

NSLog(@"the width of yourLabel is %f", widthIs);
Aaron Saunders
la source
41
Juste une remarque: c'est obsolète depuis iOS7. Le moyen préféré est maintenant:[yourString boundingRectWithSize:maximumLabelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName:yourLabel.font } context:nil];
Norbert
17
Vous pouvez également utiliser la propriété IntrinsicContentSize. Je ne suis pas très intéressé par Objective-c, mais cela devrait être quelque chose comme ceci: self.yourLabel.intrinsicContentSize cela vous donnera la taille du contenu de l'étiquette, vous pourrez donc simplement obtenir la largeur à partir de là.
Boris
1
Fonctionne yourLabel.intrinsicContentSize.widthtrès bien, vérifiez la réponse ci-dessous.
denis_lor
156

yourLabel.intrinsicContentSize.widthpour Objective-C / Swift

Jakub Truhlář
la source
ne fonctionne pas pour moi, il ne calcule pas la hauteur de largeur des étiquettes sur la base de leur texte
Chandni
1
Fonctionne parfaitement pour moi, avec une police personnalisée également!
fl034
1
réponse parfaite pour obtenir la largeur de l'étiquette dynamique
Chetan
52

En rapide

 yourLabel.intrinsicContentSize().width 
Arshad
la source
3
Cette réponse n'est valable que pour une vue aménagée
rommex
33

La réponse sélectionnée est correcte pour iOS 6 et inférieur.

Dans iOS 7, sizeWithFont:constrainedToSize:lineBreakMode:est obsolète . Il est maintenant recommandé d'utiliser boundingRectWithSize:options:attributes:context:.

CGRect expectedLabelSize = [yourString boundingRectWithSize:sizeOfRect
                                                    options:<NSStringDrawingOptions>
                                                 attributes:@{
                                                    NSFontAttributeName: yourString.font
                                                    AnyOtherAttributes: valuesForAttributes
                                                 }
                                                    context:(NSStringDrawingContext *)];

Notez que la valeur de retour n'est CGRectpas un CGSize. J'espère que cela aidera les personnes qui l'utilisent dans iOS 7.

Chetan Shenoy
la source
12

Dans iOS8, sizeWithFont est obsolète, veuillez vous référer à

CGSize yourLabelSize = [yourLabel.text sizeWithAttributes:@{NSFontAttributeName : [UIFont fontWithName:yourLabel.font size:yourLabel.fontSize]}];

Vous pouvez ajouter tous les attributs souhaités dans sizeWithAttributes. Autres attributs que vous pouvez définir:

- NSForegroundColorAttributeName
- NSParagraphStyleAttributeName
- NSBackgroundColorAttributeName
- NSShadowAttributeName

etc. Mais tu n'auras probablement pas besoin des autres

Jarora
la source
10

Swift 4 Answer qui utilise la contrainte

label.text = "Hello World"

var rect: CGRect = label.frame //get frame of label
rect.size = (label.text?.size(attributes: [NSFontAttributeName: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))! //Calculate as per label font
labelWidth.constant = rect.width // set width to Constraint outlet

Swift 5 Answer qui utilise la contrainte

label.text = "Hello World"

var rect: CGRect = label.frame //get frame of label
rect.size = (label.text?.size(withAttributes: [NSAttributedString.Key.font: UIFont(name: label.font.fontName , size: label.font.pointSize)!]))! //Calculate as per label font
labelWidth.constant = rect.width // set width to Constraint outlet
Vie iOS
la source
1
Génial! Pratique pour calculer la largeur d'UIButton en fonction du texte, où intrinsicContentSize.width ne fonctionne pas toujours correctement.
nomnom
8
CGRect rect = label.frame;
rect.size = [label.text sizeWithAttributes:@{NSFontAttributeName : [UIFont fontWithName:label.font.fontName size:label.font.pointSize]}];
label.frame = rect;
Honey Lakhani
la source
2
Cela ne répond pas à la question. Pour critiquer ou demander des éclaircissements à un auteur, laissez un commentaire sous son message - vous pouvez toujours commenter vos propres messages, et une fois que vous avez une réputation suffisante, vous pourrez commenter n'importe quel article .
The Humble Rat
cette réponse explique comment ajuster la taille de l'étiquette en fonction du texte. quel est le problème?
Honey Lakhani
2

Voici quelque chose que j'ai trouvé après avoir appliqué quelques principes à d'autres articles SO, y compris le lien d'Aaron:

    AnnotationPin *myAnnotation = (AnnotationPin *)annotation;

    self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];
    self.backgroundColor = [UIColor greenColor];
    self.frame = CGRectMake(0,0,30,30);
    imageView = [[UIImageView alloc] initWithImage:myAnnotation.THEIMAGE];
    imageView.frame = CGRectMake(3,3,20,20);
    imageView.layer.masksToBounds = NO;
    [self addSubview:imageView];
    [imageView release];

    CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]];
    CGRect newFrame = self.frame;
    newFrame.size.height = titleSize.height + 12;
    newFrame.size.width = titleSize.width + 32;
    self.frame = newFrame;
    self.layer.borderColor = [UIColor colorWithRed:0 green:.3 blue:0 alpha:1.0f].CGColor;
    self.layer.borderWidth = 3.0;

    UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(26,5,newFrame.size.width-32,newFrame.size.height-12)];
    infoLabel.text = myAnnotation.title;
    infoLabel.backgroundColor = [UIColor clearColor];
    infoLabel.textColor = [UIColor blackColor];
    infoLabel.textAlignment = UITextAlignmentCenter;
    infoLabel.font = [UIFont systemFontOfSize:12];

    [self addSubview:infoLabel];
    [infoLabel release];

Dans cet exemple, j'ajoute une épingle personnalisée à une classe MKAnnotation qui redimensionne un UILabel en fonction de la taille du texte. Il ajoute également une image sur le côté gauche de la vue, de sorte que vous voyez une partie du code gérant l'espacement approprié pour gérer l'image et le remplissage.

La clé est d'utiliser CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]];puis de redéfinir les dimensions de la vue. Vous pouvez appliquer cette logique à n'importe quelle vue.

Bien que la réponse d'Aaron fonctionne pour certains, cela n'a pas fonctionné pour moi. C'est une explication beaucoup plus détaillée que vous devriez essayer immédiatement avant d'aller ailleurs si vous voulez une vue plus dynamique avec une image et un UILabel redimensionnable. J'ai déjà fait tout le travail pour vous !!

pourquoi
la source