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
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 .
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 ...
- nombre de lignes: 0
- Sauts De Ligne: Clip
- Réduction Automatique: Minimum De Police À L'Échelle De 0,25
minimumFontSize
est obsolète dans iOS 6.
utilisez minimumScaleFactor
au lieu de minmimumFontSize
.
lbl.adjustsFontSizeToFitWidth=YES;
lbl.minimumScaleFactor=0.5;
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.
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
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)
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 :)
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
}
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.
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
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.)
Dans iOS 9 j'ai juste eu à:
- ajouter des contraintes de la gauche et de la droite de l'étiquette à la superview.
- définit le mode de coupure de ligne en IB.
- 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...
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.
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];
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:
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!
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".
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)
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)