2009-03-03 15 views
301

Ho il seguente codice di ...Come si aggiunge il testo multilinea a un UIButton?

UILabel *buttonLabel = [[UILabel alloc] initWithFrame:targetButton.bounds]; 
buttonLabel.text = @"Long text string"; 
[targetButton addSubview:buttonLabel]; 
[targetButton bringSubviewToFront:buttonLabel]; 

... l'idea è che posso avere testo su più righe per il pulsante, ma il testo è sempre oscurata dalla BackgroundImage del UIButton. Una chiamata di registrazione per mostrare le sottoview del pulsante mostra che UILabel è stato aggiunto, ma il testo stesso non può essere visto. Si tratta di un bug in UIButton o sto facendo qualcosa di sbagliato?

+3

'button.titleLabel .numberOfLines = 0 ' – ma11hew28

+1

Nota per questo molto molto vecchio QA , nel moderno Xcode ** MOLTO SEMPLICE, SCEGLIERE "TESTO ATTRIBUITO" ** e poi è banale, seleziona "A capo personaggio". – Fattie

+0

Vedere anche [risposta aggiornata] (http://stackoverflow.com/a/7832414/199364) a una domanda simile. – ToolmakerSteve

risposta

608

Per iOS 6 e, soprattutto, utilizzare il seguente per consentire a più linee:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 
// you probably want to center it 
button.titleLabel.textAlignment = NSTextAlignmentCenter; // if you want to 
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal]; 

Per iOS 5 e versioni successive utilizzare il follo ala per consentire a più linee:

button.titleLabel.lineBreakMode = UILineBreakModeWordWrap; 
// you probably want to center it 
button.titleLabel.textAlignment = UITextAlignmentCenter; 
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal]; 

2017, per iOS9 avanti,

in generale, basta fare queste due cose:

  1. scegliere "testo attribuito"
  2. nel popup "Interruzione di riga" seleziona "A capo automatico"
+5

Si noti che questi incarichi sono obsoleti in iOS 6. Vedere la risposta seguente di @NiKKi per la sintassi aggiornata. –

+3

Solo così la gente lo sa: questo non funziona se stai usando NSAttributedString –

+12

In realtà, aggiungi button.titleLabel.numberOfLines = 0; Ciò renderà le linee illimitate. E button.titleLabel.textAlignment = NSTextAlignmentLeft; se si desidera il testo giustificato a sinistra poiché il titolo è centrato per impostazione predefinita. – RyJ

7

Prima di tutto, è necessario essere consapevoli del fatto che UIButton ha già un UILabel al suo interno. È possibile impostarlo utilizzando –setTitle:forState:.

Il problema con il vostro esempio è che è necessario impostare la proprietà numberOfLines di UILabel su qualcosa di diverso dal suo valore predefinito 1. Si dovrebbe anche rivedere la proprietà lineBreakMode.

+0

Sono a conoscenza della proprietà del titolo, ma per quanto posso dire è impossibile impostarlo per utilizzare più di una riga, quindi questo approccio. Se disattivo il backgroundImage, appare la mia UILabel, che a mio avviso suggerisce un bug in bringSubviewToFront o UIButton stesso. –

-1

Anche se va bene aggiungere una sottoview a un controllo, non è garantito che funzioni effettivamente, perché il controllo potrebbe non aspettarsi che sia lì e potrebbe quindi comportarsi male. Se riesci a farla franca, aggiungi l'etichetta come vista di pari livello del pulsante e imposta la sua cornice in modo che si sovrapponga al pulsante; fino a quando è impostato per apparire in cima al pulsante, nulla che il pulsante possa fare lo oscurerà.

In altre parole:

[button.superview addSubview:myLabel]; 
myLabel.center = button.center; 
+1

Per favore, se suggerisci almeno questo tipo di approccio brutto, non fare errori nell'esempio di codice :). L'etichetta non dovrebbe avere lo stesso centro del pulsante se è una sottoview. Usa myLabel.frame = button.bounds; oppure myLabel.center = cgPointMake (button.frame.size.with * 0.5, button.frame.size.height * 0.5) – JakubKnejzlik

+1

@GrizzlyNetch Ti sto specificatamente consigliando * non * di aggiungerlo come sottoview del pulsante. 'addSubview:' qui lo aggiunge alla superview di 'button', rendendolo un fratello del pulsante, quindi la corrispondenza dei loro centri è corretta. –

+0

Ah, mio ​​errore! Hai ragione, ho perso il "piccolo" fatto che è nella superview: D ... mi dispiace :) – JakubKnejzlik

3

Per quanto riguarda l'idea di Brent di mettere il titolo UILabel come vista fratello, non sembra a me come una buona idea. Continuo a pensare a problemi di interazione con UILabel a causa dei suoi eventi di tocco che non passano attraverso la vista di UIButton.

D'altra parte, con un UILabel come sottoview di UIButton, sono abbastanza sicuro sapendo che gli eventi di tocco verranno sempre propagati alla superview di UILabel.

Ho fatto questo approccio e non ho notato nessuno dei problemi segnalati con backgroundImage. Ho aggiunto questo codice nel -titleRectForContentRect: di una sottoclasse UIButton ma il codice può anche essere inserito nella routine di disegno della superview di UIButton, che in questo caso sostituirà tutti i riferimenti a self con la variabile di UIButton.

#define TITLE_LABEL_TAG 1234 

- (CGRect)titleRectForContentRect:(CGRect)rect 
{ 
    // define the desired title inset margins based on the whole rect and its padding 
    UIEdgeInsets padding = [self titleEdgeInsets]; 
    CGRect titleRect = CGRectMake(rect.origin.x + padding.left, 
            rect.origin.x + padding.top, 
            rect.size.width - (padding.right + padding.left), 
            rect.size.height - (padding.bottom + padding].top)); 

    // save the current title view appearance 
    NSString *title = [self currentTitle]; 
    UIColor *titleColor = [self currentTitleColor]; 
    UIColor *titleShadowColor = [self currentTitleShadowColor]; 

    // we only want to add our custom label once; only 1st pass shall return nil 
    UILabel *titleLabel = (UILabel*)[self viewWithTag:TITLE_LABEL_TAG]; 


    if (!titleLabel) 
    { 
     // no custom label found (1st pass), we will be creating & adding it as subview 
     titleLabel = [[UILabel alloc] initWithFrame:titleRect]; 
     [titleLabel setTag:TITLE_LABEL_TAG]; 

     // make it multi-line 
     [titleLabel setNumberOfLines:0]; 
     [titleLabel setLineBreakMode:UILineBreakModeWordWrap]; 

     // title appearance setup; be at will to modify 
     [titleLabel setBackgroundColor:[UIColor clearColor]]; 
     [titleLabel setFont:[self font]]; 
     [titleLabel setShadowOffset:CGSizeMake(0, 1)]; 
     [titleLabel setTextAlignment:UITextAlignmentCenter]; 

     [self addSubview:titleLabel]; 
     [titleLabel release]; 
    } 

    // finally, put our label in original title view's state 
    [titleLabel setText:title]; 
    [titleLabel setTextColor:titleColor]; 
    [titleLabel setShadowColor:titleShadowColor]; 

    // and return empty rect so that the original title view is hidden 
    return CGRectZero; 
} 

Mi sono preso il tempo e ho scritto un po 'di più su questo here. Lì, indico anche una soluzione più breve, anche se non si adatta perfettamente a tutti gli scenari e coinvolge alcune attività di pirateria privata. Inoltre, puoi scaricare una sottoclasse UIButton pronta per essere utilizzata.

0

Roll your own class class. È di gran lunga la soluzione migliore a lungo termine. UIButton e altre classi UIKit sono molto restrittive su come personalizzarle.

10

C'è un modo molto più semplice:

someButton.lineBreakMode = UILineBreakModeWordWrap; 

(Edit per iOS 3 e versioni successive :)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap; 
+4

UIButton.lineBreakMode era deprecato in 3.0, quindi non è più una buona opzione. –

+1

lineBreakMode è deprecato solo come proprietà diretta di UIButton.Siamo diretti a "Utilizzare invece la proprietà lineBreakMode di titleLabel". Ho modificato la risposta di Valerii di conseguenza. È ancora una buona opzione. – Wienke

28

di riaffermare il suggerimento di Roger Nolan, ma con il codice esplicito, questa è la soluzione generale:

button.titleLabel?.numberOfLines = 0 
1

Funziona perfettamente.

Add utilizzare questo con file di configurazione come Plist, è necessario utilizzare CDATA per scrivere il titolo multilined, in questo modo:

<string><![CDATA[Line1 
Line2]]></string> 
4

Per coloro che utilizzano Xcode 4 di storyboard, è possibile fare clic sul pulsante e nella parte destra del pannello Utilità in Impostazioni, vedrai un'opzione per Interruzione di riga. Scegli Word Wrap e dovresti essere pronto.

+0

Sembra funzionare ma non si centra quando lo ho provato –

53

per iOS 6:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 
button.titleLabel.textAlignment = NSTextAlignmentCenter; 

Come

UILineBreakModeWordWrap and UITextAlignmentCenter 

sono obsoleti in IOS 6 in poi ..

+0

All'interno di 'NSText.h' nella' Foundation' non è stato aggiunto alcun elemento. È disponibile da 6.0 ma non deprecato. –

+0

a Swift: 'button.titleLabel .lineBreakMode = NSLineBreakMode.ByWordWrapping' ' button.titleLabel .textAlignment = NSTextAlignment.Center' – jcity

3

risposte qui ti dicono come raggiungere titolo tasto righe di codice.

Volevo solo aggiungere che se si stanno usando gli storyboard, è possibile digitare [Ctrl + Invio] per forzare una nuova riga in un campo titolo del pulsante.

HTH

2

Se si utilizza layout automatico su iOS 6 potrebbe anche essere necessario impostare la proprietà preferredMaxLayoutWidth:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 
button.titleLabel.textAlignment = NSTextAlignmentCenter; 
button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width; 
9

a Sinistra Centrato sulla iOS7 con autolayout:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 
button.titleLabel.textAlignment = NSTextAlignmentLeft; 
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; 
109

Il la risposta selezionata è corretta ma se preferisci fare questo genere di cose in Interface Builder puoi fare questo:

pic

2

L'impostazione della riga BreakMode su NSLineBreakByWordWrapping (in IB o in codice) rende l'etichetta del pulsante su più righe, ma non influisce sulla cornice del pulsante.

Se il pulsante ha un titolo dinamico, c'è un trucco: mettere UILabel nascosto con lo stesso carattere e legare la sua altezza all'altezza del pulsante con il layout; quando si imposta il testo su pulsante e l'etichetta e l'autolayout eseguiranno tutto il lavoro.

Nota

formato altezza intrinseca pulsante one-linea è più grande di etichetta, in modo da prevenire l'altezza dell'etichetta termoretraibile è verticale che abbraccia Priority contenuto deve essere maggiore contenuto verticale del pulsante resistenza alla compressione.

36

Se si desidera aggiungere un pulsante con il titolo centrato con più linee, impostare le impostazioni del Interface Builder per il pulsante:

[here]

+0

Si può aggiungere una descrizione testuale di come raggiungere questo obiettivo??. Un'immagine è fantastica, ma se diventa non disponibile la tua risposta sarà inutile. –

+1

@RoryMcCrossan Ciao, ho aggiunto un'immagine sopra. Puoi vederlo? Nota: Xcode 7 è ancora buggato, quindi il titolo del pulsante potrebbe scomparire. Tuttavia, una volta eseguita l'app, otterrai il risultato desiderato. – user5440039

+2

Questa è la migliore risposta in questo thread, in realtà. Funziona immediatamente e mostra il testo centrato da IB. Grazie! – RainCast

2

Se si utilizza la configurazione automatica.

button.titleLabel?.adjustsFontSizeToFitWidth = true 
button.titleLabel?.numberOfLines = 2 
14

SWIFT 3

button.titleLabel?.lineBreakMode = .byWordWrapping 
button.titleLabel?.textAlignment = .center 
button.setTitle("Button\nTitle",for: .normal) 
1
self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping 

self.btnError.titleLabel?.textAlignment = .center 

self.btnError.setTitle("Title", for: .normal) 
1

È necessario aggiungere questo codice:?

buttonLabel.titleLabel.numberOfLines = 0; 
Problemi correlati