J'ai cet étrange problème et je le traite depuis plus de 8 heures maintenant. En fonction de la situation, je dois calculer la taille UILabels
de manière dynamique,
par exemple
ma UIViewController
reçoit un événement et je change de UILabels
taille. du plus grand au plus petit. La taille de ma UILabel
devient plus petite et la taille requise est correcte, mais le texte dans ma UILabel
reste identique, la même taille de police, etc. J'ai besoin que la police soit plus petite pour que tout le texte s'adapte à la UILabel
. La question est donc de savoir comment adapter le texte à mon étiquette avec autoshrinking
ou quelque chose du genre.
Dans ma xib
, UILabels
autoshrink
est cochée, aussi le nombre de lignes est défini sur 0, et ma chaîne comporte de nouveaux symboles de ligne (\ n) et j'ai sélectionné linebreakmode to wordwrap
. Peut-être que quelqu'un était dans la même situation que moi et pourrait m'aider? Ça me plairait vraiment.
Merci d'avance!
EDIT: UILabel
la taille de police minimale est fixée à 10
Si vous cherchez toujours 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’adapter la chaîne de titre au rectangle de délimitation de l’étiquette. (Cette propriété est effective uniquement lorsque la propriété numberOfLines est définie sur 1.)
@property(nonatomic) BOOL adjustsFontSizeToFitWidth
Une valeur booléenne indiquant si l'espacement entre les lettres doit être ajusté pour correspondre à la chaîne située dans le rectangle de délimitation de l'étiquette.
@property(nonatomic) BOOL adjustsLetterSpacingToFitWidth
minimumFontSize
est obsolète dans iOS 6.
Utilisez donc minimumScaleFactor
au lieu de minmimumFontSize
.
lbl.adjustsFontSizeToFitWidth=YES;
lbl.minimumScaleFactor=0.5;
ma solution est aussi l'étiquette booléenne.adjustsFontSizeToFitWidth = YES; BUT. Vous devez, dans l’interface Builder, basculer l’option Word Wrapping sur "CLIP" . Ensuite, réduisez automatiquement 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 ça
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 attendant votre réponse
Ceci est pour Swift 3 sous Xcode 8.2.1 (8C1002)
La meilleure solution que j'ai trouvée consiste à définir une largeur fixe dans votre Storyboard ou dans votre IB sur l'étiquette. Définissez vos contraintes avec contraindre aux marges. Dans votre viewDidLoad, ajoutez 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 ne déborde pas sur une nouvelle ligne et réduit le texte à la largeur de l'étiquette sans problèmes étranges et fonctionne dans Swift 3.
Dans Swift 3 (par programme), je devais le faire:
let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)
En fin de compte, 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: autoshrink sur un UILabel avec plusieurs lignes
La solution consiste à calculer la hauteur du texte à une largeur donnée et, si le texte est plus grand, à réduire la taille de la police, puis à refaire la même chose jusqu'à ce que la hauteur soit égale ou inférieure à la taille souhaitée.
Je ne comprends pas pourquoi cela devrait être si difficile à mettre en œuvre. Si quelque chose me manque, tout le monde est invité à me corriger :)
Je pense que vous pouvez écrire le code ci-dessous après alloc init Label
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];
Ça marche bien avec moi. Utilise-le
Deux ans plus tard, et cette question est toujours d'actualité ...
Dans iOS 8/XCode 6.1, je constatais parfois que ma UILabel
(créée dans une UITableViewCell
, avec AutoLayout activé et des contraintes souples lui permettant de disposer de beaucoup d'espace) ne se redimensionnait pas pour s'adapter à la chaîne de texte.
La solution, comme les années précédentes, consistait à définir le texte et puis call sizeToFit
.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
. . .
cell.lblCreatedAt.text = [note getCreatedDateAsString];
[cell.lblCreatedAt sizeToFit];
}
(Soupir.)
Sous iOS 9, je devais simplement:
Quelqu'un a recommandé de définir le nombre de lignes sur 0, mais pour moi, cela a simplement obligé l'étiquette à afficher plusieurs lignes.
C'est une excellente question, car il semblerait que cela ferait déjà partie de la fonctionnalité intégrée UIKit
ou d'un cadre associé. Voici un bon exemple visuel de la question:
Il n'y a pas de solution facile, mais c'est tout à fait possible. Pour cela, vous pouvez essayer différentes tailles de police par programmation jusqu'à ce que vous en trouviez une qui s'adapte raisonnablement aux limites de la vue. Vous pouvez accomplir cela 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 qu'une approche complète de la force brute. Certaines considérations sont également un peu plus complexes, notamment le bon habillage de Word et les performances de la mise en cache des polices iOS, si vous recherchez quelque chose de vraiment robuste.
Si vous souhaitez uniquement afficher facilement le texte à l'écran, 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 automatique efficace des polices pour tout texte saisi, y compris les lignes multiples. Pour l'utiliser, vous feriez simplement 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 tout! Vous pouvez trouver la source complète ici: https://github.com/FlickType/AccessibilityKit
J'espère que cela t'aides!
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];
Voici comment le faire. Supposons le message suivantLabel est l’étiquette que vous voulez avoir pour l’effet souhaité. Maintenant, essayez ces simples lignes 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.
Arriver en retard à la fête, mais comme j'avais l'exigence supplémentaire d'avoir un mot par ligne, cette addition m'a fait l'affaire:
label.numberOfLines = [labelString componentsSeparatedByString:@" "].count;
Docs Apple dire:
Normalement, le texte de l'étiquette est dessiné avec la police que vous spécifiez dans la propriété de police. Toutefois, si cette propriété est définie sur OUI et que le texte de la propriété dépasse le rectangle de délimitation de l'étiquette, le destinataire commence à réduire la taille de la police jusqu'à ce que la chaîne soit ajustée ou que la taille de police minimale soit atteinte. Sous iOS 6 et versions antérieures, cette propriété est effective uniquement lorsque la propriété numberOfLines est définie sur 1.
Mais c'est un mensonge. Un mensonge je vous le dis! C'est vrai pour toutes les versions d'iOS. En particulier, cela est vrai lorsque vous utilisez une UILabel
dans une UICollectionViewCell
dont la taille est déterminée par des contraintes ajustées dynamiquement à l'exécution via une présentation personnalisée (ex. self.menuCollectionViewLayout.itemSize = size
).
Ainsi, lorsqu'il est utilisé conjointement avec adjustsFontSizeToFitWidth
et minimumScaleFactor
, comme indiqué dans les réponses précédentes, la définition par programme de numberOfLines
en fonction du nombre de mots a résolu le problème de la réduction automatique de la taille. Faire quelque chose de similaire en fonction du nombre de mots ou même du nombre de caractères peut produire une solution "suffisamment proche".
Dans Swift 4 (par programme):
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 un label dans une cellule de vue de collection , et le texte de l'étiquette était en train d'être 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)