UILabel ne rétrécit pas automatiquement le texte en fonction de la taille de l'étiquette

j'ai cette étrange question, et je m'en occupe depuis plus de 8 heures maintenant.. Selon la situation, je dois calculer la taille UILabels de façon dynamique,

E. g

my UIViewController reçoit un événement et je change UILabels taille. des plus grands aux plus petits. La taille de mon UILabel devient plus petite et j'obtiens la taille correcte nécessaire, mais le texte de mon UILabel reste le même, la même taille de police et etc. J'ai besoin de la police pour obtenir plus petit, pour le texte entier pour correspondre au UILabel . La question est donc de savoir comment adapter le texte à mon étiquette avec autoshrinking ou quelque chose comme ça?

dans mon xib , UILabels autoshrink est cochée, aussi nombre de lignes est mis à 0, et aussi ma chaîne a de nouveaux symboles de ligne (n), et j'ai sélectionné linebreakmode à wordwrap . Peut-être que n'importe qui était dans la même situation que moi maintenant, et pourrait - il m'aider? Je voudrais vraiment l'apprécier.

Merci à l'avance!

modifier: UILabel la taille minimale de police est fixée à 10

95
demandé sur Forge 2012-03-28 17:16:48

17 réponses

dans le cas où vous êtes toujours à la recherche d'une meilleure solution, je pense que c'est ce que vous voulez:

une valeur booléenne indiquant si la taille de la police doit être réduite afin d'ajuster la chaîne de titre dans le rectangle limite de l'étiquette. (cette propriété n'est effective que lorsque la propriété numberOfLines est définie à 1.)

@property(nonatomic) BOOL adjustsFontSizeToFitWidth

une valeur booléenne indiquant si l'espacement entre les lettres devrait être ajusté pour s'adapter à la chaîne dans le rectangle des limites du label.

@property(nonatomic) BOOL adjustsLetterSpacingToFitWidth

Source .

141
répondu lester 2016-10-21 13:45:22

C'est ainsi que J'obtiens le travail UILabel Autoshrink (en particulier pour la hauteur de la police d'étiquette dans le dispositif 4s de 6s Plus Storyboard) dans iOS 9.2, Xcode 7.2 ...

enter image description here

  • nombre de lignes: 0
  • Sauts De Ligne: Clip
  • Réduction Automatique: Minimum De Police À L'Échelle De 0,25
95
répondu ohho 2015-12-15 07:29:14

minimumFontSize est obsolète dans iOS 6.

utilisez minimumScaleFactor au lieu de minmimumFontSize .

lbl.adjustsFontSizeToFitWidth=YES;
lbl.minimumScaleFactor=0.5;
56
répondu Iulian Onofrei 2014-12-09 11:50:30

aussi ma solution est l'étiquette booléenne.adjustsFontSizeToFitWidth = YES; MAIS. Vous devez dans le constructeur de l'interface le mot Wrapping commutateur en " CLIP ". Ensuite, autoshrink les étiquettes. C'est très important.

18
répondu loki-e 2014-06-25 08:43:20

vous pouvez écrire comme

UILabel *reviews = [[UILabel alloc]initWithFrame:CGRectMake(14, 13,270,30)];//Set frame
reviews.numberOfLines=0;
reviews.textAlignment = UITextAlignmentLeft;
reviews.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size:12];
reviews.textColor=[UIColor colorWithRed:0.0/255.0 green:0.0/255.0 blue:0.0/255.0 alpha:0.8]; 
reviews.backgroundColor=[UIColor clearColor];

vous pouvez calculer le nombre de lignes comme cela

CGSize maxlblSize = CGSizeMake(270,9999);
CGSize totalSize = [reviews.text sizeWithFont:reviews.font 
              constrainedToSize:maxlblSize lineBreakMode:reviews.lineBreakMode];

CGRect newFrame =reviews.frame;
newFrame.size.height = totalSize.height;
reviews.frame = newFrame;

CGFloat reviewlblheight = totalSize.height;

int lines=reviewlblheight/12;//12 is the font size of label

UILabel *lbl=[[UILabel alloc]init];
lbl.frame=CGRectMake(140,220 , 100, 25);//set frame as your requirement
lbl.font=[UIFont fontWithName:@"Arial" size:20];
[lbl setAutoresizingMask:UIViewContentModeScaleAspectFill];
[lbl setLineBreakMode:UILineBreakModeClip];
lbl.adjustsFontSizeToFitWidth=YES;//This is main for shrinking font
lbl.text=@"HelloHelloHello";

J'espère que cela vous aidera :-) en attente de votre réponse

5
répondu Birju 2014-07-25 20:51:40

dans Swift 3 (Programmatiquement) j'ai dû faire ceci:

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)
4
répondu Naloiko Eugene 2017-03-09 14:09:13

finalement, je n'ai pas trouvé ma réponse. Et je pense que l'autoshrink ne fonctionne pas pour plusieurs lignes. J'ai fini par utiliser suggestion dans ce lien: réduction automatique sur un UILabel avec de multiples lignes

la solution est de caluler la hauteur du texte à une largeur donnée et, si le texte est plus grand, de rétrécir la taille de la police, puis de le faire à nouveau jusqu'à ce que la hauteur soit égale ou inférieure à votre taille nécessaire.

je ne comprends pas pourquoi cela devrait être si difficile à mettre en œuvre. Si je manque quelque chose, tout le monde est le bienvenu pour me corriger :)

3
répondu Lukas 2017-05-23 11:47:32

C'est pour Swift 3 Xcode 8.2.1 ( 8C1002)

la meilleure solution que j'ai trouvée est de définir une largeur fixe dans votre Storyboard ou IB sur l'étiquette. Définissez vos contraintes avec la contrainte aux marges. Dans votre viewDidLoad ajouter les lignes de code suivantes:

override func viewDidLoad() {
            super.viewDidLoad()

            label.numberOfLines = 1
            label.adjustsFontSizeToFitWidth = true
            label.minimumScaleFactor = 0.5
        }

label constraints to margin

fixed width label constraints to margin

attributes inspector

cela a fonctionné comme un charme et il ne déborde pas sur une nouvelle ligne et rétrécit le texte pour correspondre à la largeur du label sans aucun problème bizarre et fonctionne dans Swift 3.

3
répondu Robert Mcelvenny 2017-03-05 14:13:42

je pense que vous pouvez écrire le code ci-dessous après l'étiquette allocit

UILabel* lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, 280, 50)];
lbl.text = @"vbdsbfdshfisdhfidshufidhsufhdsf dhdsfhdksbf hfsdh fksdfidsf sdfhsd fhdsf sdhfh sdifsdkf ksdhfkds fhdsf dsfkdsfkjdhsfkjdhskfjhsdk fdhsf ";
[lbl setMinimumFontSize:8.0];
[lbl setNumberOfLines:0];
[lbl setFont:[UIFont systemFontOfSize:10.0]];
lbl.lineBreakMode = UILineBreakModeWordWrap;
lbl.backgroundColor = [UIColor redColor];
[lbl sizeToFit];
[self.view addSubview:lbl];

C'est de travailler avec moi amende Utilisation

2
répondu iDhaval 2012-05-11 12:07:28

deux ans après, et cette question est toujours d'actualité...

dans iOS 8 / XCode 6.1, je trouvais parfois que mon UILabel (créé dans un UITableViewCell , avec AutoLayout activé, et des contraintes flexibles de sorte qu'il avait beaucoup d'espace) ne se redimensionnerait pas pour s'adapter à la chaîne de texte.

la solution, comme les années précédentes, était de régler le texte, et puis appel sizeToFit .

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    . . .
    cell.lblCreatedAt.text = [note getCreatedDateAsString];
    [cell.lblCreatedAt sizeToFit];
}

(Soupir.)

2
répondu Mike Gledhill 2015-02-20 09:50:00

Dans iOS 9 j'ai juste eu à:

  1. ajouter des contraintes de la gauche et de la droite de l'étiquette à la superview.
  2. définit le mode de coupure de ligne en IB.
  3. fixe le nombre de lignes à 1 en IB.

Quelqu'un a recommandé de fixer le nombre de lignes à 0, mais pour moi cela vient de faire passer l'étiquette à plusieurs lignes...

2
répondu Nick Yap 2016-03-08 15:48:29

Voici comment faire.Supposons que le message suivant soit l'étiquette que vous voulez avoir l'effet désiré.Maintenant, essayez ces lignes simples de codes:

    //SET THE WIDTH CONSTRAINTS FOR LABEL.
    CGFloat constrainedWidth = 240.0f;//YOU CAN PUT YOUR DESIRED ONE,THE MAXIMUM WIDTH OF YOUR LABEL.
 //CALCULATE THE SPACE FOR THE TEXT SPECIFIED.
    CGSize sizeOfText=[yourText sizeWithFont:yourFont constrainedToSize:CGSizeMake(constrainedWidth, CGFLOAT_MAX) lineBreakMode:UILineBreakModeWordWrap];
    UILabel *messageLabel=[[UILabel alloc] initWithFrame:CGRectMake(20,20,constrainedWidth,sizeOfText.height)];
    messageLabel.text=yourText;
    messageLabel.numberOfLines=0;//JUST TO SUPPORT MULTILINING.
1
répondu Anand 2012-03-28 13:39:47

ne fonctionne pas si numberOfLines > 1 Ce que j'ai fait une condition comme celle - ci,

if(lblRecLocation.text.length > 100)
    lblRecLocation.font = [UIFont fontWithName:@"app_font_name" size:10];
1
répondu Vaibhav Saran 2012-06-28 06:23:08

c'est une grande question, parce qu'il se sent comme si cela ferait partie de la fonctionnalité intégrée UIKit ou un cadre connexe maintenant. Voici un bon exemple visuel de la question:

Font resizing animation

il n'y a pas de solution facile, mais c'est certainement possible. Une façon de le faire est de programmer différentes tailles de police jusqu'à ce que vous en trouviez une qui s'adapte assez près des limites de la vue. Vous pouvez accomplir ceci avec la fonction boundingRect() de NSString ou NSAttributedString . Par exemple:

let string = "This is a test"
let infiniteSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height:CGFloat.greatestFiniteMagnitude)
let size = string.boundingRect(with: infiniteSize, options: [], attributes: [.font: UIFont.systemFont(ofSize: avgSize)] context: nil).size

Vous pouvez faire une recherche binaire pour être plus efficace, une approche par force brute. Il y a aussi quelques considérations qui sont un peu plus impliquées, y compris l'emballage correct de mots et la performance de mise en cache de police iOS, si vous cherchez quelque chose de vraiment robuste.

si vous vous souciez seulement de montrer le texte sur l'écran d'une manière facile, J'ai développé une implémentation robuste dans Swift, que j'utilise également dans une application de production. C'est une sous-classe UIView avec une mise à l'échelle efficace et automatique pour n'importe quel texte d'entrée, y compris les lignes multiples. Pour l'utiliser, il suffit de faire quelque chose comme:

let view = AKTextView()
// Use a simple or fancy NSAttributedString
view.attributedText = .init(string: "Some text here")
// Add to the view hierarchy somewhere

C'est ça! Vous pouvez trouver la source complète ici: https://github.com/FlickType/AccessibilityKit

Espérons que cette aide!

1
répondu Kosta Eleftheriou 2018-09-12 23:38:11

venant en retard à la partie, mais depuis que j'ai eu la condition supplémentaire d'avoir un mot par ligne, cet ajout a fait l'astuce pour moi:

label.numberOfLines = [labelString componentsSeparatedByString:@" "].count;

Apple Docs say:

Normalement, le texte de l'étiquette est tiré avec la police que vous spécifiez dans la propriété font. Si cette propriété est définie à Oui, cependant, et que le texte de la propriété text dépasse la limite de l'étiquette rectangle, le récepteur commence à réduire la taille de la police jusqu'à ce que la chaîne corresponde ou que la taille minimale de la police soit atteinte. In iOS 6 and earlier, cette propriété n'est effective que lorsque la propriété numberOfLines est définie à 1.

, Mais c'est un mensonge. Un mensonge, je vous dis! C'est vrai pour toutes les versions de iOS. Plus précisément, cela est vrai lorsqu'on utilise un UILabel dans un UICollectionViewCell pour lequel la taille est déterminée par des contraintes ajustées dynamiquement. à l'exécution via la disposition personnalisée(ex. self.menuCollectionViewLayout.itemSize = size ).

ainsi , lorsqu'il est utilisé en conjonction avec adjustsFontSizeToFitWidth et minimumScaleFactor , comme mentionné dans les réponses précédentes, le réglage programmatique numberOfLines basé sur le nombre de mots a résolu le problème d'autoshrink. Faire quelque chose de similaire basé sur le nombre de mots ou même le nombre de caractères pourrait produire une solution "assez proche".

0
répondu Justin Whitney 2016-05-02 16:31:45

Dans Swift 4 (Par Programmation):

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200.0, height: 200.0))
label.adjustsFontSizeToFitWidth = true
label.numberOfLines = 0

label.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

view.addSubview(label)
0
répondu Lazar Pešić 2018-04-24 13:02:59

Swift 4, Xcode 9.4.1

la solution qui a fonctionné pour moi: J'avais une étiquette dans une cellule d'affichage de la collection , et le texte de l'étiquette était découpé. Définissez les attributs comme ci-dessous sur Storyboard

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)
0
répondu Naishta 2018-09-24 12:44:14