Come si fa ad aggiungere testo su più righe per un UIButton?

voti
313

Ho il codice seguente...

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 i subviews del tasto mostra che l'UILabel è stato aggiunto, ma il testo stesso non può essere visto. Si tratta di un bug in UIButton o sto facendo qualcosa di sbagliato?

È pubblicato 03/03/2009 alle 01:22
fonte dall'utente
In altre lingue...                            


26 risposte

voti
618

Per iOS 6 e superiore, utilizzare la seguente per consentire più righe:

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 utilizzare i seguenti 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 in avanti ,

in generale, basta fare queste due cose:

  1. scegliere "testo attribuito"
  2. il pop-up "Line Break" selezionare "A capo automatico"
Risposto il 01/12/2009 a 23:34
fonte dall'utente

voti
114

La risposta selezionata è corretta, ma se si preferisce fare questo genere di cose in Interface Builder si può fare questo:

pic

Risposto il 14/05/2014 a 16:36
fonte dall'utente

voti
53

Per iOS 6:

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

Come

UILineBreakModeWordWrap and UITextAlignmentCenter

sono obsoleti in IOS 6 in avanti ..

Risposto il 08/10/2012 a 08:14
fonte dall'utente

voti
41

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

[ Qui]

Risposto il 21/10/2015 a 09:03
fonte dall'utente

voti
28

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

button.titleLabel?.numberOfLines = 0
Risposto il 28/10/2010 a 16:45
fonte dall'utente

voti
17

SWIFT 3

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.textAlignment = .center  
button.setTitle("Button\nTitle",for: .normal)
Risposto il 08/05/2017 a 09:56
fonte dall'utente

voti
10

C'è un modo molto più semplice:

someButton.lineBreakMode = UILineBreakModeWordWrap;

(Edit per iOS 3 e successive :)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
Risposto il 25/10/2009 a 20:48
fonte dall'utente

voti
9

A sinistra Allinea l'iOS7 con autolayout:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentLeft;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
Risposto il 28/06/2013 a 20:07
fonte dall'utente

voti
7

Prima di tutto, si deve essere consapevoli che UIButton ha già un UILabel al suo interno. È possibile impostare utilizzando –setTitle:forState:.

Il problema con il vostro esempio è che è necessario impostare di UILabel numberOfLinesproprietà a qualcosa di diverso rispetto al suo valore predefinito di 1. Si dovrebbe anche rivedere la lineBreakModeproprietà.

Risposto il 03/03/2009 a 09:35
fonte dall'utente

voti
4

Le risposte qui si spiegano come ottenere il titolo pulsante righe di codice.

Volevo solo aggiungere che se si utilizza storyboard, è possibile digitare [Ctrl + Invio] per forzare un ritorno a capo in un campo titolo tasto.

HTH

Risposto il 01/05/2013 a 10:50
fonte dall'utente

voti
4

Per coloro che utilizzano Xcode 4 di storyboard, è possibile fare clic sul pulsante, e sul lato destro Utilità riquadro Attributi sotto l'ispettore, vedrete un'opzione per Interruzione di riga. Scegli capo automatico, e si dovrebbe essere pronti per partire.

Risposto il 09/05/2012 a 19:12
fonte dall'utente

voti
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 l'UILabel grazie ai suoi eventi di tocco non ottenere attraverso di vista della UIButton.

D'altra parte, con un UILabel come visualizzazione secondaria del UIButton, sono abbastanza confortevole sapendo che gli eventi touch saranno sempre propagate superview del UILabel.

Ho preso 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 posizionato nella redazione di routine del superview UIButton, che in questo caso si deve sostituire tutti i riferimenti a sé con la variabile del 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;
}

Ho fatto prendere il tempo e ho scritto un po 'di più su questo qui . Lì ho anche sottolineare una soluzione più breve, anche se non abbastanza bene per tutti gli scenari e coinvolge alcune viste private di hacking. Inoltre lì, è possibile scaricare una sottoclasse UIButton pronto per essere utilizzato.

Risposto il 09/03/2009 a 15:25
fonte dall'utente

voti
2

È necessario aggiungere questo codice:

buttonLabel.titleLabel.numberOfLines = 0;
Risposto il 21/02/2018 a 11:41
fonte dall'utente

voti
2

Se si utilizza la configurazione automatica.

button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.numberOfLines = 2
Risposto il 09/12/2016 a 10:55
fonte dall'utente

voti
2

Impostazione lineBreakMode a NSLineBreakByWordWrapping (sia in IB o codice) rende etichetta pulsante multilinea, ma non influisce cornice del pulsante.

Se il pulsante ha titolo dinamico, c'è un trucco: mettere UILabel nascosto con lo stesso tipo di carattere e cravatta è l'altezza all'altezza del pulsante con il layout; testo quando impostato a pulsante e l'etichetta e autolayout farà tutto il lavoro.

Nota

formato altezza intrinseca del 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.

Risposto il 31/08/2015 a 20:21
fonte dall'utente

voti
2

Se si utilizza la configurazione automatica su iOS 6 potrebbe anche essere necessario impostare la preferredMaxLayoutWidthproprietà:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width;
Risposto il 01/05/2013 a 19:45
fonte dall'utente

voti
2

Funziona perfettamente.

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

<string><![CDATA[Line1
Line2]]></string>
Risposto il 11/05/2011 a 11:04
fonte dall'utente

voti
1
self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping

self.btnError.titleLabel?.textAlignment = .center

self.btnError.setTitle("Title", for: .normal)
Risposto il 03/08/2017 a 09:40
fonte dall'utente

voti
0

In Swift 5.0 e Xcode 10.2

SharedClass esempio scrivere una volta e utilizzare ogni ware

Questa è la classe condiviso (come questo si utilizza tutte le proprietà componenti)

import UIKit

class SharedClass: NSObject {

     static let sharedInstance = SharedClass()

     private override init() {

     }
  }

//UIButton extension
extension UIButton {
     //UIButton properties
     func btnMultipleLines() {
         titleLabel?.numberOfLines = 0
         titleLabel?.lineBreakMode = .byWordWrapping
         titleLabel?.textAlignment = .center        
     }
}

Nella tua ViewController chiamata come questo

button.btnMultipleLines()//This is your button
Risposto il 29/04/2019 a 07:54
fonte dall'utente

voti
0

Ho avuto un problema con la configurazione automatica, dopo aver abilitato multi-linea il risultato è stato in questo modo: in modo che la dimensione non influenza la dimensione del pulsante di Ho aggiunto basa sulla (in questo caso era contentEdgeInsets (10, 10, 10, 10 ) dopo la chiamata : spero che tu (swift 5.0 aiuta):
entrare descrizione dell'immagine qui
titleLabel
ConstraintscontentEdgeInsets
makeMultiLineSupport()
entrare descrizione dell'immagine qui

extension UIButton {

    func makeMultiLineSupport() {
        guard let titleLabel = titleLabel else {
            return
        }
        titleLabel.numberOfLines = 0
        titleLabel.setContentHuggingPriority(.required, for: .vertical)
        titleLabel.setContentHuggingPriority(.required, for: .horizontal)
        addConstraints([
            .init(item: titleLabel,
                  attribute: .top,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .top,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.top),
            .init(item: titleLabel,
                  attribute: .bottom,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .bottom,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.bottom),
            .init(item: titleLabel,
                  attribute: .left,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .left,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.left),
            .init(item: titleLabel,
                  attribute: .right,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .right,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.right)
            ])
    }

}
Risposto il 11/04/2019 a 21:25
fonte dall'utente

voti
0

In questi giorni, se si ha realmente bisogno di questo genere di cose per essere accessibile in Interface Builder, caso per caso, è possibile farlo con una semplice estensione come questo:

extension UIButton {
    @IBInspectable var numberOfLines: Int {
        get { return titleLabel?.numberOfLines ?? 1 }
        set { titleLabel?.numberOfLines = newValue }
    }
}

Poi si può semplicemente impostare NumberOfLines come un attributo su qualsiasi UIButton o UIButton sottoclasse come se si trattasse di un'etichetta. Lo stesso vale per tutta una serie di altri valori solitamente-inaccessibili, come il raggio angolo dello strato di vista, o gli attributi del ombra che getta.

Risposto il 17/11/2018 a 07:12
fonte dall'utente

voti
0

In Xcode 9.3 è possibile farlo utilizzando storyboard come qui di seguito,

entrare descrizione dell'immagine qui

È necessario impostare il titolo pulsante TextAlignment per centrare

button.titleLabel?.textAlignment = .center

Non è necessario impostare il testo del titolo con la nuova linea (\ n) come qui di seguito,

button.setTitle("Good\nAnswer",for: .normal)

Basta impostare titolo,

button.setTitle("Good Answer",for: .normal)

Ecco il risultato,

entrare descrizione dell'immagine qui

Risposto il 31/05/2018 a 06:14
fonte dall'utente

voti
0

Ho incorporato la risposta di jessecurry entro STAButton che fa parte dei miei STAControls libreria open source. Attualmente uso all'interno di una delle applicazioni sto sviluppando e funziona per le mie esigenze. Sentitevi liberi di aprire questioni su come migliorarlo o manda me tirare le richieste.

Risposto il 05/05/2018 a 23:27
fonte dall'utente

voti
0

swift 4.0

btn.titleLabel?.lineBreakMode = .byWordWrapping
btn.titleLabel?.textAlignment = .center
btn.setTitle( "Line1\nLine2", for: .normal)
Risposto il 25/03/2018 a 12:50
fonte dall'utente

voti
0

Stendete la propria classe pulsante. E 'di gran lunga la migliore soluzione a lungo termine. UIButton e le altre classi UIKit sono molto restrittive nel modo in cui è possibile personalizzare.

Risposto il 10/03/2009 a 14:16
fonte dall'utente

voti
-3

Anche se è giusto per aggiungere una visualizzazione secondaria a un controllo, non c'è alcuna garanzia che sarà in realtà il lavoro, perché il controllo potrebbe non aspettatevi di essere lì e potrebbe quindi si comportano male. Se si riesce a farla franca, basta aggiungere l'etichetta come una vista fratello del pulsante e impostare il telaio in modo che si sovrapponga il tasto; fintanto che è impostato per comparire in cima al tasto, il pulsante nulla può fare oscurerà esso.

In altre parole:

[button.superview addSubview:myLabel];
myLabel.center = button.center;
Risposto il 03/03/2009 a 13:04
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more