UILabel - Etikett mit automatischer Größe für Text?

144

Ist es möglich, die Größe des UILabel-Felds / der Grenzen automatisch an den enthaltenen Text anzupassen? (Es ist mir egal, ob es größer als das Display ist)

Wenn also ein Benutzer "Hallo" eingibt oder "mein Name ist wirklich lang, ich möchte, dass er in dieses Feld passt", wird er niemals abgeschnitten und das Etikett wird entsprechend "erweitert"?

Wayneh
quelle
Jeder bitte helfen Sie mir mit der Bereitstellung von schnellen Codes ..
Angel F Syrus

Antworten:

98

Bitte überprüfen Sie meine Liste, in der ich eine Kategorie für UILabeletwas sehr Ähnliches erstellt habe. In meiner Kategorie kann eine UILabelStrecke ihre Höhe anzeigen , um den gesamten Inhalt anzuzeigen : https://gist.github.com/1005520

Oder lesen Sie diesen Beitrag: https://stackoverflow.com/a/7242981/662605

Dies würde die Höhe dehnen, aber Sie können es leicht ändern, um in die andere Richtung zu arbeiten und die Breite mit so etwas zu dehnen. Ich glaube, was Sie tun möchten:

@implementation UILabel (dynamicSizeMeWidth)

- (void)resizeToStretch{
    float width = [self expectedWidth];
    CGRect newFrame = [self frame];
    newFrame.size.width = width;
    [self setFrame:newFrame];
}

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize maximumLabelSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX);

    CGSize expectedLabelSize = [[self text] sizeWithFont:[self font] 
                                            constrainedToSize:maximumLabelSize
                                            lineBreakMode:[self lineBreakMode]]; 
    return expectedLabelSize.width;
}

@end

Sie können einfacher die in sizeToFitder UIViewKlasse verfügbare Methode verwenden , aber die Anzahl der Zeilen aus Sicherheitsgründen auf 1 setzen.


iOS 6 Update

Wenn Sie AutoLayout verwenden, verfügen Sie über eine integrierte Lösung. Wenn Sie die Anzahl der Zeilen auf 0 setzen, ändert das Framework die Größe Ihrer Beschriftung entsprechend (indem Sie mehr Höhe hinzufügen), um sie an Ihren Text anzupassen.


iOS 8 Update

sizeWithFont:ist veraltet, verwenden Sie sizeWithAttributes:stattdessen:

- (float)expectedWidth{
    [self setNumberOfLines:1];

    CGSize expectedLabelSize = [[self text] sizeWithAttributes:@{NSFontAttributeName:self.font}];

    return expectedLabelSize.width;
}
Daniel
quelle
8
Mit der iOS 6 AutoLayout-Methode hatte ich eine Höhenbeschränkung für mein Etikett, die ich nicht loswerden konnte. Durch Festlegen der Beziehung der Höhenbeschränkung auf "Größer als oder gleich" konnte die Höhe vergrößert werden.
Michael Luton
2
sizeWithFont: beschränkteToSize: lineBreakMode: Methode in ios 7
Karan Alangat
1
UILabel ändert die Größe nicht selbst, wenn der Text kleiner / größer ist. Ich benutze Auto-Layout. Versucht, UILabel zu erstellen, aber sie werden jedes Mal erstellt, wenn cellForRowAtIndex initialisiert wird. Versuchte viele Dinge. Nichts funktioniert für mich. Hintergrund von Uilabel nehmen die gleiche Breite. Hilfe !!!
CoreDeviOS
@ Daniel Ich habe die Anzahl der Zeilen auf 0 gesetzt, aber es funktioniert nicht. Ich habe die Einschränkungen für die horizontale und vertikale Mitte festgelegt. Eine zusätzliche Sache, die ich getan habe, ist, eine Unterklasse von UILABEL zu erstellen und sie für dieses Label zu verwenden
Jasmeet
Mit Autolayout ist dies die einfachste Lösung für: (1) Setzen von Linien auf 0, (2) Setzen der Breitenbeschränkung auf "Größer als oder gleich" mit Konstante 0, (3) Setzen der Höhenbeschränkung auf "Größer als oder gleich" mit Konstante 0, ( 4) Richten Sie es wie gewohnt aus, indem Sie es beispielsweise horizontal und vertikal zentrieren.
Erik van der Neut
76

Mit [label sizeToFit];wird das gleiche Ergebnis aus der Daniels-Kategorie erzielt.

Obwohl ich empfehle, Autolayout zu verwenden und die Größe des Etiketts aufgrund von Einschränkungen ändern zu lassen.

Guilherme Torres Castro
quelle
3
Bei Verwendung von Swift musste ich dies im Hauptthread mit dispatch_async ausführen (dispatch_get_main_queue (), {});
Zeezer
@Zeezer weißt du warum?
FurloSK
13
@FurloSK Alle Änderungen an der Benutzeroberfläche müssen im Hauptthread vorgenommen werden.
Guilherme Torres Castro
32

Wenn wir möchten, dass UILabeldas basierend auf der Textgröße verkleinert und erweitert wird, ist ein Storyboard mit Autolayout die beste Option. Nachfolgend finden Sie die Schritte, um dies zu erreichen

Schritte

  1. Setzen Sie UILabel in den View Controller und platzieren Sie es, wo immer Sie wollen. Auch 0für numberOfLinesEigentum von setzen UILabel.

  2. Geben Sie die Beschränkung für Top-, Leading- und Trailing-Space-Pins ein.

Geben Sie hier die Bildbeschreibung ein

  1. Jetzt wird eine Warnung ausgegeben. Klicken Sie auf den gelben Pfeil.

Geben Sie hier die Bildbeschreibung ein

  1. Klicken Sie auf Update Frameund klicken Sie auf Fix Misplacement. Jetzt wird dieses UILabel verkleinert, wenn der Text kleiner ist, und erweitert, wenn der Text mehr ist.
Yogesh Suthar
quelle
1
Ich habe nicht auf Lokalisierung getestet, aber es sollte auch dafür funktionieren.
Yogesh Suthar
2
Ich konnte dies nicht mit einem vorhandenen Projekt zum Laufen bringen, bis ich das Kontrollkästchen "Bevorzugte Breite" "Explizit" deaktiviert hatte. Dann funktionierte alles einwandfrei.
zorro2b
25

Dies ist nicht so kompliziert wie einige der anderen Antworten.

Geben Sie hier die Bildbeschreibung ein

Stecken Sie die linken und oberen Kanten fest

Verwenden Sie einfach das automatische Layout, um Einschränkungen hinzuzufügen, um die linke und obere Seite des Etiketts zu fixieren.

Geben Sie hier die Bildbeschreibung ein

Danach wird die Größe automatisch geändert.

Anmerkungen

  • Fügen Sie keine Einschränkungen für die Breite und Höhe hinzu. Etiketten haben eine intrinsische Größe, die auf ihrem Textinhalt basiert.
  • Vielen Dank an diese Antwort für die Hilfe.
  • Bei sizeToFitVerwendung des automatischen Layouts ist keine Einstellung erforderlich . Mein vollständiger Code für das Beispielprojekt ist hier:

    import UIKit
    class ViewController: UIViewController {
    
        @IBOutlet weak var myLabel: UILabel!
    
        @IBAction func changeTextButtonTapped(sender: UIButton) {
            myLabel.text = "my name is really long i want it to fit in this box"
        }
    }
  • Wenn Sie möchten, dass Ihr Etikett Zeilenumbruch macht, setzen Sie die Anzahl der Zeilen in IB auf 0 und fügen Sie myLabel.preferredMaxLayoutWidth = 150 // or whateverCode hinzu. (Ich habe meinen Knopf auch am unteren Rand des Etiketts befestigt, damit er sich nach unten bewegt, wenn die Etikettenhöhe zunimmt.)

Geben Sie hier die Bildbeschreibung ein

  • Wenn Sie nach Etiketten mit dynamischer Größe in a suchen, UITableViewCellsehen Sie diese Antwort .

Geben Sie hier die Bildbeschreibung ein

Suragch
quelle
Hallo, ich habe das Etikett in der Größe geändert, aber ich verstehe nicht, wie die Größe der Zelle geändert werden soll. Können Sie mir bitte mitteilen, wie die Größe der Zelle geändert werden kann?
Vivek
@Vivek, solange Sie keine Einschränkungen für die Höhe festgelegt haben, sollte die Größe automatisch geändert werden.
Suragch
Ja, aber wie ist es möglich, wenn ich eine benutzerdefinierte Zelle verwende und 2 Etiketten in seine Zelle lege?
Vivek
@ Vivek, sorry, ich habe deine Frage falsch verstanden. Haben Sie mit dieser Antwort bereits ein Etikett zum Laufen gebracht ?
Suragch
9

Verwenden Sie [label sizeToFit];diese Option, um den Text in UILabel anzupassen

Gaurav Gilani
quelle
5

Ich habe einige Methoden basierend auf Daniels Antwort oben erstellt.

-(CGFloat)heightForLabel:(UILabel *)label withText:(NSString *)text
{
    CGSize maximumLabelSize     = CGSizeMake(290, FLT_MAX);

    CGSize expectedLabelSize    = [text sizeWithFont:label.font
                                constrainedToSize:maximumLabelSize
                                    lineBreakMode:label.lineBreakMode];

    return expectedLabelSize.height;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label
{
    CGRect newFrame         = label.frame;
    newFrame.size.height    = [self heightForLabel:label withText:label.text];
    label.frame             = newFrame;
}

-(void)resizeHeightToFitForLabel:(UILabel *)label withText:(NSString *)text
{
    label.text              = text;
    [self resizeHeightToFitForLabel:label];
}
Doug Baker
quelle
5

Folgendes finde ich für meine Situation:

1) Die Höhe des UILabel hat eine Einschränkung von> = 0 bei Verwendung des automatischen Layouts. Die Breite ist fest. 2) Weisen Sie den Text dem UILabel zu, das zu diesem Zeitpunkt bereits eine Übersicht hat (nicht sicher, wie wichtig das ist). 3) Dann machen Sie:

    label.sizeToFit()
    label.layoutIfNeeded()

Die Höhe des Etiketts ist jetzt entsprechend eingestellt.

Chris Prince
quelle
3
@implementation UILabel (UILabel_Auto)

- (void)adjustHeight {

    if (self.text == nil) {
        self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.bounds.size.width, 0);
        return;
    }

    CGSize aSize = self.bounds.size;
    CGSize tmpSize = CGRectInfinite.size;
    tmpSize.width = aSize.width;

    tmpSize = [self.text sizeWithFont:self.font constrainedToSize:tmpSize];

    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, aSize.width, tmpSize.height);
}

@end

Dies ist eine Kategoriemethode. Sie müssen zuerst Text festlegen und dann diese Methode aufrufen, um die Höhe von UILabel anzupassen.

Kaijay Lu
quelle
2

Sie können die Größe Ihres Etiketts nach Text und anderen zugehörigen Steuerelementen auf zwei Arten anpassen:

  1. Für iOS 7.0 und höher

    CGSize labelTextSize = [labelText boundingRectWithSize:CGSizeMake(labelsWidth, MAXFLOAT)
                                              options:NSStringDrawingUsesLineFragmentOrigin
                                           attributes:@{
                                                        NSFontAttributeName : labelFont
                                                        }
                                              context:nil].size;

vor iOS 7.0 konnte dies zur Berechnung der Etikettengröße verwendet werden

CGSize labelTextSize = [label.text sizeWithFont:label.font 
                            constrainedToSize:CGSizeMake(label.frame.size.width, MAXFLOAT)  
                                lineBreakMode:NSLineBreakByWordWrapping];

// andere Steuerelemente basierend auf labelTextHeight neu gestalten

CGFloat labelTextHeight = labelTextSize.height;
  1. Wenn Sie die Größe des Etikettentextes nicht berechnen möchten, können Sie -sizeToFit für die Instanz von UILabel as- verwenden.

    [label setNumberOfLines:0]; // for multiline label
    [label setText:@"label text to set"];
    [label sizeToFit];// call this to fit size of the label according to text

// Danach können Sie den Beschriftungsrahmen dazu bringen, andere verwandte Steuerelemente neu zu gestalten

vijeesh
quelle
2
  1. Fügen Sie fehlende Einschränkungen im Storyboard hinzu.
  2. Wählen Sie UILabel im Storyboard und setzen Sie die Attribute "Line" auf 0.
  3. Ref Geben Sie das UILabel mit der ID: label an Controller.h aus
  4. Controller.m und fügen Sie [label sizeToFit];in viewDidLoad hinzu
user2941395
quelle
1

Ich hatte große Probleme mit dem automatischen Layout. Wir haben zwei Container in der Tabellenzelle. Die Größe des zweiten Containers hängt von der Artikelbeschreibung ab (0 - 1000 Zeichen), und die Größe der Zeile sollte basierend darauf geändert werden.

Die fehlende Zutat war die unterste Einschränkung für die Beschreibung.

Ich habe die untere Einschränkung des dynamischen Elements von = 0 auf > = 0 geändert .

Bojan Tadic
quelle
Das hat mir das Leben gerettet. Wenn Sie versuchen zu folgen: github.com/honghaoz/… ist dies die richtige Antwort.
Justin Fyles
0

Passt immer! :) :)

    name.text = @"Hi this the text I want to fit to"
    UIFont * font = 14.0f;
    CGSize size = [name.text sizeWithAttributes:@{NSFontAttributeName: font}];
    nameOfAssessment.frame = CGRectMake(400, 0, size.width, 44);
    nameOfAssessment.font = [UIFont systemFontOfSize:font];
HannahCarney
quelle
0

Sie können eine Zeilenausgabe anzeigen und dann die Eigenschaft Line = 0 und die Ausgabe mehrerer Zeilen anzeigen und dann die Eigenschaft Line = 1 und mehr festlegen

[self.yourLableName sizeToFit];
Dixit Akabari
quelle
-1

Es gibt auch diesen Ansatz:

[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];
Dave Cole
quelle
Ich war es nicht, der diese Antwort abgelehnt hat, aber ich wollte nur darauf hinweisen, dass ich keine changeTextWithAutoHeight:width:Methode sehen kann UILabel. Könnten Sie bitte einen Link angeben, wo in der UIKit-Dokumentation diese Methode zu finden ist?
Adil Hussain