UILabel - etichetta con dimensioni automatiche per adattarsi al testo?


144

È possibile ridimensionare automaticamente la casella / i limiti di UILabel per adattarli al testo contenuto? (Non mi interessa se finisce più grande del display)

Quindi se un utente inserisce "ciao" o "il mio nome è davvero lungo, voglio che si adatti a questa casella", non viene mai troncato e l'etichetta viene "ampliata" di conseguenza?


Qualcuno, per favore, mi aiuti a fornire codici rapidi ...
Angel F Syrus,

Risposte:


98

Per favore, dai un'occhiata alla mia idea per cui ho creato una categoria per UILabelqualcosa di molto simile, la mia categoria fa UILabelallungare la sua altezza per mostrare tutto il contenuto: https://gist.github.com/1005520

Oppure dai un'occhiata a questo post: https://stackoverflow.com/a/7242981/662605

Questo allungherebbe l'altezza, ma puoi cambiarlo facilmente per lavorare nell'altro modo e allungare la larghezza con qualcosa del genere, che credo sia quello che vuoi fare:

@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

Puoi semplicemente utilizzare il sizeToFitmetodo disponibile dalla UIViewclasse, ma imposta il numero di righe su 1 per sicurezza.


aggiornamento iOS 6

Se stai usando AutoLayout, allora hai una soluzione integrata. Impostando il numero di righe su 0, il framework ridimensionerà l'etichetta in modo appropriato (aggiungendo più altezza) per adattarlo al testo.


aggiornamento iOS 8

sizeWithFont:è deprecato quindi utilizzare sizeWithAttributes:invece:

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

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

    return expectedLabelSize.width;
}

8
Usando il metodo AutoLayout di iOS 6 ho finito con un vincolo di altezza sulla mia etichetta di cui non riuscivo a liberarmi. Impostando la relazione del vincolo di altezza su "Maggiore o uguale" è stato possibile aumentare l'altezza.
Michael Luton,

2
sizeWithFont: vincoloToSize: lineBreakMode: metodo deprecato in iOS 7
Karan Alangat,

1
UILabel non si ridimensiona se il testo è inferiore / maggiore. sto usando Auto-layout. Ho provato a creare UILabel ma sono creati ogni volta che cellForRowAtIndex viene inizializzato. Ho provato molte cose. Niente funziona per me. Lo sfondo di uilabel ha la stessa larghezza. Aiuto !!!
coreDeviOS il

@Daniel Ho impostato il numero di righe = 0, ma non funziona. Ho impostato i vincoli del centro in orizzontale e in verticale. Un'altra cosa che ho fatto è stata creare una sottoclasse di UILABEL e usarla per
quell'etichetta

Con Autolayout la soluzione più semplice per: (1) Impostare le linee su 0, (2) Impostare il vincolo di larghezza su "Maggiore o uguale" con Costante 0, (3) Impostare il vincolo di altezza su "Maggiore o uguale" con Costante 0, ( 4) Allinea come faresti normalmente, ad esempio centrando orizzontalmente e verticalmente.
Erik van der Neut,

76

L'utilizzo [label sizeToFit];otterrà lo stesso risultato dalla categoria Daniels.

Anche se raccomando di utilizzare il layout automatico e di ridimensionare l'etichetta in base a vincoli.


3
Quando ho usato swift ho dovuto eseguirlo sul thread principale usando dispatch_async (dispatch_get_main_queue (), {});
Zeezer,

@Zeezer sai perché?
FurloSK,

13
@FurloSK Eventuali modifiche all'interfaccia utente devono essere eseguite nel thread principale.
Guilherme Torres Castro,

32

Se vogliamo che UILabeldovrebbe ridursi ed espandersi in base alle dimensioni del testo, lo storyboard con autolayout è l'opzione migliore. Di seguito sono riportati i passaggi per raggiungere questo obiettivo

passi

  1. Metti UILabel nel controller di visualizzazione e posizionalo dove vuoi. Anche messo 0per numberOfLinesproprietà di UILabel.

  2. Dai il vincolo del perno dello spazio superiore, iniziale e finale.

inserisci qui la descrizione dell'immagine

  1. Ora ti avviserà, fai clic sulla freccia gialla.

inserisci qui la descrizione dell'immagine

  1. Fare clic su Update Framee fare clic su Fix Misplacement. Ora questo UILabel si ridurrà se il testo è minore ed espanderà se il testo è maggiore.

1
Non ho ancora testato la localizzazione, ma dovrebbe funzionare anche per quello.
Yogesh Suthar,

2
Non sono riuscito a farlo funzionare con un progetto esistente fino a quando non ho deselezionato la casella "Explicit" "Larghezza preferita", quindi tutto ha funzionato bene.
zorro2b,

25

Questo non è così complicato come alcune delle altre risposte lo fanno.

inserisci qui la descrizione dell'immagine

Pin i bordi sinistro e superiore

Basta usare il layout automatico per aggiungere vincoli per bloccare i lati sinistro e superiore dell'etichetta.

inserisci qui la descrizione dell'immagine

Successivamente verrà ridimensionato automaticamente.

Appunti

  • Non aggiungere vincoli per larghezza e altezza. Le etichette hanno una dimensione intrinseca in base al loro contenuto testuale.
  • Grazie a questa risposta per l'aiuto in questo.
  • Non è necessario impostare sizeToFitquando si utilizza il layout automatico. Il mio codice completo per il progetto di esempio è qui:

    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"
        }
    }
  • Se vuoi che la tua etichetta sia a capo, quindi imposta il numero di linee su 0 in IB e aggiungi il myLabel.preferredMaxLayoutWidth = 150 // or whatevercodice. (Ho anche bloccato il mio pulsante nella parte inferiore dell'etichetta in modo che si spostasse verso il basso quando l'altezza dell'etichetta aumentava.)

inserisci qui la descrizione dell'immagine

  • Se stai cercando etichette dimensionate dinamicamente all'interno di un, UITableViewCellvedi questa risposta .

inserisci qui la descrizione dell'immagine


Ciao, ho ottenuto l'etichetta ridimensionata ma non capisco come ridimensionare l'altezza della cella. Potete per favore fatemi sapere come ridimensionare l'altezza della cella.
Vivek,

@Vivek, fintanto che non hai alcun vincolo impostato sull'altezza, dovrebbe ridimensionarsi automaticamente.
Suragch,

Sì, ma come è possibile quando utilizzo la cella personalizzata e inserisco 2 etichette nella sua cella.
Vivek,

@Vivek, scusa, ho letto male la tua domanda. Hai già ottenuto un'etichetta funzionante passando attraverso questa risposta ?
Suragch,


5

Ho creato alcuni metodi basati sulla risposta di Daniel sopra.

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

5

Ecco cosa trovo lavori per la mia situazione:

1) L'altezza di UILabel ha un vincolo> = 0 usando il layout automatico. La larghezza è fissa 2) Assegna il testo a UILabel, che a quel punto ha già una superview (non sono sicuro di quanto sia vitale). 3) Quindi, fai:

    label.sizeToFit()
    label.layoutIfNeeded()

L'altezza dell'etichetta è ora impostata in modo appropriato.


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

Questo è il metodo di categoria. Devi prima impostare il testo, quindi chiama questo metodo per regolare l'altezza di UILabel.


2

Puoi dimensionare l'etichetta in base al testo e ad altri controlli correlati utilizzando due modi:

  1. Per iOS 7.0 e versioni successive

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

prima di iOS 7.0 questo poteva essere usato per calcolare la dimensione dell'etichetta

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

// riformatta altri controlli in base a labelTextHeight

CGFloat labelTextHeight = labelTextSize.height;
  1. Se non si desidera calcolare la dimensione del testo dell'etichetta, è possibile utilizzare -sizeToFit sull'istanza di UILabel come-

    [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

// dopo questo puoi ottenere la cornice dell'etichetta per riformulare altri controlli correlati


2
  1. Aggiungi vincoli mancanti nello storyboard.
  2. Seleziona UILabel nello storyboard e imposta gli attributi "Linea" su 0.
  3. Rifoutare UILabel su Controller.h con id: label
  4. Controller.m e aggiungi [label sizeToFit];in viewDidLoad

1

Ho avuto enormi problemi con il layout automatico. Abbiamo due contenitori all'interno della cella della tabella. Il secondo contenitore viene ridimensionato in base alla descrizione dell'articolo (0 - 1000 caratteri) e la riga deve essere ridimensionata in base a essi.

L'ingrediente mancante era il limite inferiore per la descrizione.

Ho modificato il vincolo inferiore dell'elemento dinamico da = 0 a > = 0 .


Questo mi ha salvato la vita. Se stai tentando di seguire: github.com/honghaoz/… questa è la risposta corretta.
Justin Fyles,

0

Si adatta sempre! :)

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

0

puoi mostrare un output di riga quindi impostare la proprietà Line = 0 e mostrare output di più righe quindi impostare la proprietà Line = 1 e altro

[self.yourLableName sizeToFit];

-1

C'è anche questo approccio:

[self.myLabel changeTextWithAutoHeight:self.myStringToAssignToLabel width:180.0f];

Non sono stato io a sottovalutare questa risposta, ma volevo solo sottolineare che non riesco a vedere un changeTextWithAutoHeight:width:metodo UILabel. Potresti fornire un link per favore in cui nella documentazione di UIKit è possibile trovare questo metodo.
Adil Hussain,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.