wake-up-neo.com

UILabel verkleinert den Text nicht automatisch auf die Etikettengröße

Ich habe dieses seltsame Problem, und ich beschäftige mich jetzt seit mehr als 8 Stunden damit. Abhängig von der Situation muss ich UILabels Größe dynamisch berechnen,
z.B 
mein UIViewController empfängt ein Ereignis und ich UILabels-Größe. von größer zu kleiner. Die Größe meines UILabel wird kleiner und ich bekomme die korrekte benötigte Größe, aber der Text in meinem UILabel bleibt derselbe, die gleiche Schriftgröße und usw. Ich brauche die Schrift, um kleiner zu werden, damit der gesamte Text zum UILabel passt. Die Frage ist also, wie man den Text mit autoshrinking oder so ähnlich an mein Label anpasst?

In meiner xib ist UILabelsautoshrink geprüft, außerdem ist Anzahl der Zeilen auf 0 gesetzt, und auch meine Zeichenfolge enthält neue Zeilensymbole (\ n), und ich habe linebreakmode für wordwrap ausgewählt. Vielleicht war jemand in der gleichen Situation wie ich jetzt und könnte mir helfen? Das würde ich wirklich schätzen.

Danke im Voraus!

EDIT:UILabel Die minimale Schriftgröße ist auf 10 eingestellt

98
Lukas

Falls Sie immer noch nach einer besseren Lösung suchen, denke ich, dass Sie Folgendes wünschen:

Ein boolescher Wert, der angibt, ob die Schriftgröße verringert werden soll, damit die Titelzeichenfolge in das umschließende Rechteck des Etiketts passt. (Diese Eigenschaft ist nur wirksam, wenn die numberOfLines-Eigenschaft auf 1 festgelegt ist.)

@property(nonatomic) BOOL adjustsFontSizeToFitWidth

Ein boolescher Wert, der angibt, ob der Abstand zwischen den Buchstaben an die Zeichenfolge innerhalb des Begrenzungsrechtecks ​​der Beschriftung angepasst werden soll.

@property(nonatomic) BOOL adjustsLetterSpacingToFitWidth

Quelle .

146
lester

So bekomme ich UILabel Autoshrink Arbeit (besonders für die Höhe der Beschriftung der Etikettenschrift in 4s-Geräten aus 6s Plus Storyboard) in iOS 9.2, Xcode 7.2 ...

 enter image description here

  • Anzahl der Zeilen ist 0
  • Zeilenumbrüche: Clip
  • Autoshrink: Minimum Font Scale 0.25
105
ohho

minimumFontSize ist in iOS 6 veraltet.

Verwenden Sie also minimumScaleFactor anstelle von minmimumFontSize.

lbl.adjustsFontSizeToFitWidth=YES;
lbl.minimumScaleFactor=0.5;
60
user2681543

meine Lösung ist auch das boolean label.adjustsFontSizeToFitWidth = YES; ABER. Sie müssen im Interface Builder das Word Wrapping auf "CLIP" ..__ umstellen. Dann werden die Labels automatisch schrumpfen. Dies ist sehr wichtig.

18
loki-e

Du kannst gerne schreiben

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];

Sie können die Anzahl der Zeilen so berechnen

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
[email protected]"HelloHelloHello";

Ich hoffe, dies wird Ihnen helfen: -) Warten auf Ihre Antwort 

5
Birju

Dies ist für Swift 3 mit Xcode 8.2.1 (8C1002). 

Die beste Lösung, die ich gefunden habe, ist das Festlegen einer festen Breite in Ihrem Storyboard oder IB auf dem Etikett. Legen Sie Ihre Einschränkungen mit Randbedingungen fest. Fügen Sie in Ihrer viewDidLoad die folgenden Codezeilen hinzu:

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

Das funktionierte wie ein Zauber und es fließt nicht zu einer neuen Zeile über und schrumpft den Text ohne merkwürdige Probleme auf die Breite des Etiketts. Er funktioniert in Swift 3.

4

In Swift 3 (programmatisch) musste ich Folgendes tun:

let lbl = UILabel()
lbl.numberOfLines = 0
lbl.lineBreakMode = .byClipping
lbl.adjustsFontSizeToFitWidth = true
lbl.minimumScaleFactor = 0.5
lbl.font = UIFont.systemFont(ofSize: 15)
4
Naloiko Eugene

Am Ende habe ich meine Antwort nicht gefunden. Ich glaube, der Autoshrink funktioniert nicht für mehrere Zeilen. Am Ende habe ich einen Vorschlag in diesem Link verwendet: autoshrink auf einem UILabel mit mehreren Zeilen

Die Lösung besteht darin, die Texthöhe bei gegebener Breite zu berechnen. Wenn der Text größer ist, verkleinern Sie die Schriftgröße und wiederholen Sie den Vorgang, bis die Höhe der gewünschten Größe entspricht oder darunter liegt.

Ich verstehe nicht, warum dies so schwer umzusetzen ist. Wenn mir etwas fehlt, kann mich jeder korrigieren :)

3
Lukas

Ich denke, Sie können folgenden Code schreiben nach Zuteilung 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];

es funktioniert mit mir gut benutze es

2
iDhaval

Zwei Jahre später, und diese Ausgabe gibt es immer noch ...

In iOS 8/XCode 6.1 stellte ich manchmal fest, dass sich meine UILabel (erstellt in einer UITableViewCell, AutoLayout-Funktion und flexiblen Einschränkungen, damit es viel Platz hatte) selbst nicht an die Textzeichenfolge anpassen konnte.

Die Lösung bestand wie in den vergangenen Jahren darin, den Text festzulegen und dann sizeToFit aufzurufen.

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

(Seufzer.)

2
Mike Gledhill

In iOS 9 musste ich nur:

  1. Fügen Sie Einschränkungen von links und rechts von der Beschriftung zum Übersichtsfenster hinzu.
  2. Setzen Sie den Zeilenumbruchmodus in IB auf Clipping.
  3. Setzen Sie die Anzahl der Zeilen in IB auf 1.

Jemand hat empfohlen, die Anzahl der Zeilen auf 0 zu setzen, aber für mich hat das Label einfach zu mehreren Zeilen geführt ...

2
Nick Yap

Das ist eine großartige Frage, denn es fühlt sich so an, als wäre dies bereits Teil der integrierten UIKit-Funktionalität oder eines zugehörigen Frameworks. Hier ist ein gutes visuelles Beispiel für die Frage:

Font resizing animation

Es gibt keinen einfachen Weg, aber es ist definitiv möglich. Eine Möglichkeit, dies zu tun, besteht darin, verschiedene Schriftgrößen programmatisch auszuprobieren, bis Sie eine finden, die ziemlich nahe an die Grenzen der Ansicht passt. Sie können dies mit der boundingRect()-Funktion von NSString oder NSAttributedString erreichen. Zum Beispiel:

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

Sie können eine binäre Suche durchführen, um effizienter zu sein als ein vollständiger Brute-Force-Ansatz. Es gibt auch einige Überlegungen, die etwas komplizierter sind, einschließlich korrektes Word-Wrapping und iOS-Schriftarten-Caching, wenn Sie nach etwas wirklich Robustem suchen.

Wenn Sie nur den Text auf einfache Weise auf dem Bildschirm anzeigen möchten, habe ich in Swift eine robuste Implementierung entwickelt, die ich auch in einer Produktions-App verwende. Es ist eine UIView-Unterklasse mit effizienter, automatischer Skalierung von Schriftarten für beliebigen Eingabetext, einschließlich mehrerer Zeilen. Um es zu benutzen, würden Sie einfach so etwas tun:

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

Das ist es! Die vollständige Quelle finden Sie hier: https://github.com/FlickType/AccessibilityKit

Hoffe das hilft!

1

funktioniert nicht, wenn numberOfLines > 1 Was ich gemacht habe, eine Bedingung wie diese -

if(lblRecLocation.text.length > 100)
    lblRecLocation.font = [UIFont fontWithName:@"app_font_name" size:10];
1
Vaibhav Saran

Gehen Sie dazu wie folgt vor. Angenommen, das folgende messageLabel ist das Label, mit dem Sie den gewünschten Effekt erzielen möchten. Versuchen Sie nun diese einfache Codezeile:

    //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
Anand

Zu spät auf die Party gekommen, aber da ich die zusätzliche Anforderung hatte, ein Wort pro Zeile zu haben, war dieser Zusatz für mich der Trick:

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

Apple Docs sagen:

Normalerweise wird der Beschriftungstext mit der in der Eigenschaft font angegebenen Schriftart gezeichnet. Wenn diese Eigenschaft jedoch auf YES gesetzt ist und der Text in der Texteigenschaft das Begrenzungsrechteck der Beschriftung überschreitet, verringert der Empfänger die Schriftgröße, bis die Zeichenfolge passt oder die Mindestschriftgröße erreicht wird. In iOS 6 und früheren Versionen ist diese Eigenschaft nur wirksam, wenn die numberOfLines-Eigenschaft auf 1 festgelegt ist.

Aber das ist eine Lüge. Eine Lüge erzähle ich dir! Dies gilt für alle iOS-Versionen. Dies gilt insbesondere für die Verwendung einer Variable UILabel innerhalb einer Variablen UICollectionViewCell, für die die Größe durch Bedingungen bestimmt wird, die zur Laufzeit über das benutzerdefinierte Layout (z. B. self.menuCollectionViewLayout.itemSize = size) dynamisch angepasst werden.

Bei der Verwendung in Verbindung mit adjustsFontSizeToFitWidth und minimumScaleFactor, wie in den vorherigen Antworten erwähnt, konnte durch das programmgesteuerte Setzen von numberOfLines basierend auf der Word-Anzahl das Problem des automatischen Schrumpfens gelöst werden. Wenn Sie etwas Ähnliches auf der Grundlage der Anzahl der Wörter oder sogar der Anzahl der Zeichen ausführen, kann dies zu einer Lösung "nahe genug" führen.

0
Justin Whitney

In Swift 4 (programmgesteuert): 

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

Die Lösung, die für mich funktioniert hat: Ich hatte ein Label in einer Sammlungsansichtszelle , und der Labeltext wurde abgeschnitten . Legen Sie die Attribute wie folgt in Storyboard fest

Lines = 0
LineBreak = Word Wrap
Set yourlabel's leading and trailing constraint = 0 (using Autolayout)
0
Naishta