135 votes

UILabel ne rétrécit pas automatiquement le texte pour l'adapter à la taille de l'étiquette.

J'ai ce problème étrange, et je le traite depuis plus de 8 heures maintenant Selon la situation, je dois calculer UILabels la taille de façon dynamique,
Par exemple
mon UIViewController reçoit un événement et i change UILabels taille. de plus grand à plus petit. La taille de mon UILabel devient plus petit et j'obtiens la taille correcte nécessaire, mais le texte dans mon UILabel reste la même, la même taille de police, etc. J'ai besoin que la police devienne plus petite, que tout le texte s'adapte à la taille de l'écran. UILabel . La question est donc de savoir comment faire pour que le texte s'adapte à mon étiquette. autoshrinking ou quelque chose comme ça ?

Dans mon xib , UILabels autoshrink est vérifié, également nombre de lignes est fixé à 0, et aussi ma chaîne a des symboles de nouvelle ligne ( \n ), et j'ai sélectionné linebreakmode à wordwrap . Peut-être que quelqu'un s'est trouvé dans la même situation que moi et pourrait m'aider ? Je vous en serais très reconnaissant.

Merci d'avance !

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

0 votes

Quelle est la taille minimale de votre police pour l'étiquette que vous définissez s'il vous plaît ajouter.

5voto

Birju Points 675

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 suit

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 :-) Dans l'attente de votre réponse

0 votes

Donc, si je fixe le nombre de lignes à mon étiquette, le texte se rétrécit automatiquement ?

0 votes

Si votre contenu est hors de la largeur, il prendra la ligne suivante

0 votes

Hey j'ai fait comme vous l'avez suggéré, mais ça ne marche pas, pourquoi le nombre de lignes m'aiderait-il ?

4voto

Lukas Points 482

Finalement, je n'ai pas trouvé ma réponse. Et je pense que l'autoshrink ne fonctionne pas pour les lignes multiples. J'ai fini par utiliser la suggestion dans ce lien : Rétrécissement automatique d'un UILabel avec plusieurs lignes

La solution consiste à calculer la hauteur du texte pour une largeur donnée et, si le texte est plus grand, à réduire la taille de la police, puis à recommencer jusqu'à ce que la hauteur soit égale ou inférieure à la taille requise.

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

4voto

Ceci est pour Swift 3 avec 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 constrain to margins. Dans votre viewDidLoad, ajoutez 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é à merveille : il n'y a pas de débordement sur une nouvelle ligne et le texte est rétréci pour s'adapter à la largeur de l'étiquette sans aucun problème bizarre et fonctionne en Swift 3.

4voto

C'est une bonne question, parce que j'ai l'impression que ça ferait partie de l'intégration UIKit ou un cadre connexe. Voici un bon exemple visuel de la question :

Font resizing animation

Il n'y a pas de solution facile, mais c'est tout à fait possible. Une façon de procéder consiste à essayer par programme différentes tailles de police jusqu'à ce que vous en trouviez une qui s'adapte raisonnablement bien aux limites de la vue. Pour ce faire, vous pouvez utiliser la fonction boundingRect() fonction de NSString o 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 effectuer une recherche binaire pour être plus efficace qu'une approche par force brute complète. Il existe également des considérations un peu plus complexes, notamment l'habillage correct des mots et les performances de mise en cache des polices iOS, si vous recherchez quelque chose de vraiment robuste.

Si vous souhaitez uniquement afficher le texte à l'écran de manière simple, j'ai développé une implémentation robuste en Swift, que j'utilise également dans une application de production. Il s'agit d'une UIView avec une mise à l'échelle efficace et automatique des polices pour tout 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

J'espère que cela vous aidera !

3voto

yapster Points 85

Dans iOS 9, je n'avais qu'à le faire :

  1. Ajouter les contraintes de la gauche et de la droite de l'étiquette à la vue supérieure.
  2. Définissez le mode de saut de ligne sur l'écrêtage dans IB.
  3. Définissez le nombre de lignes à 1 dans IB.

Quelqu'un a recommandé de mettre le nombre de lignes à 0, mais pour moi cela a juste fait en sorte que l'étiquette aille sur plusieurs lignes...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X