Como calcular a largura do UILabel com base no comprimento do texto?

142

Eu quero exibir uma imagem ao lado de um UILabel, no entanto, o UILabel tem um comprimento de texto variável, portanto não sei onde colocar a imagem. Como posso fazer isso?

Sheehan Alam
fonte

Respostas:

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

Para que serve [[NSString sizeWithFont: forWidth: lineBreakMode:]?

esta pergunta pode ter sua resposta, funcionou para mim.


Para 2014, editei nesta nova versão, com base no comentário extremamente útil de Norbert abaixo! Isso faz tudo. Felicidades

// 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
fonte
41
Apenas uma observação: isso está obsoleto desde o iOS7. A maneira preferida agora é:[yourString boundingRectWithSize:maximumLabelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName:yourLabel.font } context:nil];
Norbert
17
Você também pode usar a propriedade IntrinsicContentSize. Não gosto muito de Objective-c, mas deve ser algo assim: self.yourLabel.intrinsicContentSize Isso fornecerá o tamanho do conteúdo do rótulo, para que você possa obter a largura a partir daí.
Boris
1
Apenas yourLabel.intrinsicContentSize.widthfunciona muito bem, verifique a resposta abaixo.
Denis_lor 6/06/19
155

yourLabel.intrinsicContentSize.widthpara Objective-C / Swift

Jakub Truhlář
fonte
Não trabalho para mim não está calculando largura altura da etiqueta na base do seu texto
Chandni
1
Funciona perfeitamente para mim, com fonte personalizada também!
fl034
1
resposta perfeita para obter largura do rótulo dinâmico
Chetan 27/01
52

Em rápido

 yourLabel.intrinsicContentSize().width 
Arshad
fonte
3
Esta resposta é válida apenas para uma exibição que foi apresentada
rommex
33

A resposta selecionada está correta para o iOS 6 e abaixo.

No iOS 7, sizeWithFont:constrainedToSize:lineBreakMode:foi preterido . Agora é recomendado que você use boundingRectWithSize:options:attributes:context:.

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

Observe que o valor de retorno CGRectnão é umCGSize . Espero que isso ajude as pessoas que o usam no iOS 7.

Chetan Shenoy
fonte
12

No iOS8 sizeWithFont foi descontinuado, consulte

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

Você pode adicionar todos os atributos desejados em sizeWithAttributes. Outros atributos que você pode definir:

- NSForegroundColorAttributeName
- NSParagraphStyleAttributeName
- NSBackgroundColorAttributeName
- NSShadowAttributeName

e assim por diante. Mas provavelmente você não precisará dos outros

jarora
fonte
10

Swift 4 Answer que está usando a restrição

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 que está usando a restrição

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
iOS Lifee
fonte
1
Ótimo! Conveniente para calcular a largura do UIButton de acordo com o texto, onde intrinsicContentSize.width nem sempre funciona corretamente.
Nomnom 5/08/19
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
fonte
2
Isso não fornece uma resposta para a pergunta. Para criticar ou solicitar esclarecimentos a um autor, deixe um comentário abaixo da postagem - você sempre pode comentar em suas próprias postagens e, quando tiver reputação suficiente , poderá comentar em qualquer post .
The Humble Rat
esta resposta informa como ajustar o tamanho da etiqueta de acordo com o texto. qual é o problema nisso?
Honey Lakhani
2

Aqui está uma coisa que eu inventei depois de aplicar alguns princípios em outras postagens da SO, incluindo o link de 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];

Neste exemplo, estou adicionando um alfinete personalizado a uma classe MKAnnotation que redimensiona um UILabel de acordo com o tamanho do texto. Ele também adiciona uma imagem no lado esquerdo da visualização, para que você veja parte do código gerenciando o espaçamento adequado para lidar com a imagem e o preenchimento.

A chave é usar CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]];e redefinir as dimensões da vista. Você pode aplicar essa lógica a qualquer visualização.

Embora a resposta de Aaron funcione para alguns, não funcionou para mim. Esta é uma explicação muito mais detalhada que você deve tentar imediatamente antes de ir para outro lugar, se desejar uma visualização mais dinâmica com uma imagem e um UILabel redimensionável. Eu já fiz todo o trabalho para você !!

whyoz
fonte