text sottolineato - Sottolineare il testo in UIButton




css html (15)

La risposta di Nick H247 ma l'approccio di Swift:

import UIKit

class UnderlineUIButton: UIButton {

    override func drawRect(rect: CGRect) {
        super.drawRect(rect)

        let textRect = self.titleLabel!.frame

        var descender = self.titleLabel?.font.descender

        var contextRef: CGContextRef = UIGraphicsGetCurrentContext();

        CGContextSetStrokeColorWithColor(contextRef, self.titleLabel?.textColor.CGColor);

        CGContextMoveToPoint(contextRef, textRect.origin.x, textRect.origin.y + textRect.size.height + descender!);

        CGContextAddLineToPoint(contextRef, textRect.origin.x + textRect.size.width, textRect.origin.y + textRect.size.height + descender!);

        CGContextClosePath(contextRef);

        CGContextDrawPath(contextRef, kCGPathStroke);
    }
}

Qualcuno può suggerire come sottolineare il titolo di un UIButton? Ho un UIButton di tipo personalizzato e voglio che il titolo sia sottolineato, ma Interface Builder non fornisce alcuna opzione per farlo.

In Interface Builder quando si seleziona l'opzione Font per un pulsante, fornisce l'opzione per selezionare Nessuno, Singolo, Doppio, Colore ma nessuno di questi fornisce alcuna modifica al Titolo sul pulsante.

Qualsiasi aiuto apprezzato.


In fretta

func underlineButton(button : UIButton) {

var titleString : NSMutableAttributedString = NSMutableAttributedString(string: button.titleLabel!.text!)
titleString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: NSMakeRange(0, button.titleLabel!.text!.utf16Count))
button.setAttributedTitle(titleString, forState: .Normal)}

La risposta di Nick è un ottimo modo veloce per farlo.

Ho aggiunto il supporto in drawRect per le ombre.

La risposta di Nick non prende in considerazione se il titolo del tuo pulsante ha un'ombra sotto il testo:

Ma puoi spostare la sottolineatura in basso all'altezza dell'ombra in questo modo:

CGFloat descender = self.titleLabel.font.descender;
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGFloat shadowHeight = self.titleLabel.shadowOffset.height;
descender += shadowHeight;

Quindi otterrai qualcosa di simile a questo:


func underline(text: String, state: UIControlState = .normal, color:UIColor? = nil) {
        var titleString = NSMutableAttributedString(string: text)

        if let color = color {
            titleString = NSMutableAttributedString(string: text,
                               attributes: [NSForegroundColorAttributeName: color])
        }

        let stringRange = NSMakeRange(0, text.characters.count)
        titleString.addAttribute(NSUnderlineStyleAttributeName,
                                 value: NSUnderlineStyle.styleSingle.rawValue,
                                 range: stringRange)

        self.setAttributedTitle(titleString, for: state)
    }

Per utilizzare il generatore di interfacce per sottolineare, è necessario:

  • Cambialo in attributo
  • Evidenzia il testo nella finestra di ispezione Attributi
  • Fare clic con il tasto destro, scegliere Carattere e quindi Sottolinea

Video qualcun altro realizzato https://www.youtube.com/watch?v=5-ZnV3jQd9I


Ecco la mia funzione, funziona in Swift 1.2.

func underlineButton(button : UIButton, text: String) {

    var titleString : NSMutableAttributedString = NSMutableAttributedString(string: text)
    titleString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.StyleSingle.rawValue, range: NSMakeRange(0, count(text.utf8)))
    button.setAttributedTitle(titleString, forState: .Normal)
}

UPDATE Estensione Swift 3.0:

extension UIButton {
    func underlineButton(text: String) {
        let titleString = NSMutableAttributedString(string: text)
        titleString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.styleSingle.rawValue, range: NSMakeRange(0, text.characters.count))
        self.setAttributedTitle(titleString, for: .normal)
    }
}

Versione Swift 3 per risposta di con colore di sottolineatura personalizzato, larghezza di riga e intervallo:

import Foundation

class UnderlinedButton: UIButton {

    private let underlineColor: UIColor
    private let thickness: CGFloat
    private let gap: CGFloat

    init(underlineColor: UIColor, thickness: CGFloat, gap: CGFloat, frame: CGRect? = nil) {
        self.underlineColor = underlineColor
        self.thickness = thickness
        self.gap = gap
        super.init(frame: frame ?? .zero)
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        guard let textRect = titleLabel?.frame,
            let decender = titleLabel?.font.descender,
            let context = UIGraphicsGetCurrentContext() else { return }

        context.setStrokeColor(underlineColor.cgColor)
        context.move(to: CGPoint(x: textRect.origin.x, y: textRect.origin.y + textRect.height + decender + gap))
        context.setLineWidth(thickness)
        context.addLine(to: CGPoint(x: textRect.origin.x + textRect.width, y: textRect.origin.y + textRect.height + decender + gap))
        context.closePath()
        context.drawPath(using: .stroke)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Per Swift 3 è possibile utilizzare la seguente estensione:

extension UIButton {
    func underlineButton(text: String) {
        let titleString = NSMutableAttributedString(string: text)
        titleString.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.styleSingle.rawValue, range: NSMakeRange(0, text.characters.count))
        self.setAttributedTitle(titleString, for: .normal)
    }
}

È molto semplice con la stringa attribuita

Crea un dizionario con gli attributi set e si applica alla stringa attribuita. Quindi puoi impostare la stringa attribuita come attibutedtitle in uibutton o attribuitotext in uilabel.

NSDictionary *attrDict = @{NSFontAttributeName : [UIFont
 systemFontOfSize:14.0],NSForegroundColorAttributeName : [UIColor
 whiteColor]};
 NSMutableAttributedString *title =[[NSMutableAttributedString alloc] initWithString:@"mybutton" attributes: attrDict]; 
[title addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0,[commentString length])]; [btnRegLater setAttributedTitle:title forState:UIControlStateNormal];

È possibile utilizzare questo codice per aggiungere sottolineatura con spaziatura nel pulsante.

  • Quando ho provato a disegnare una sottolineatura dal generatore di interfacce. Assomiglia all'immagine qui sotto.

1 - Riferimento del costruttore dell'interfaccia

  • E dopo aver usato il codice sottostante ho raggiunto il risultato come volevo.

2 - utilizzando il codice descritto

public func setTextUnderline()
    {
        let dummyButton: UIButton = UIButton.init()
        dummyButton.setTitle(self.titleLabel?.text, for: .normal)
        dummyButton.titleLabel?.font = self.titleLabel?.font
        dummyButton.sizeToFit()

        let dummyHeight = dummyButton.frame.size.height + 3

        let bottomLine = CALayer()
        bottomLine.frame = CGRect.init(x: (self.frame.size.width - dummyButton.frame.size.width)/2, y: -(self.frame.size.height - dummyHeight), width: dummyButton.frame.size.width, height: 1.0)
        bottomLine.backgroundColor = self.titleLabel?.textColor.cgColor
        self.layer.addSublayer(bottomLine)
    }

Credo che ci sia qualche bug nell'editor di font in XCode. Se si utilizza il generatore di interfacce, è necessario modificare il titolo da Normale a Attribuito, aprire TextEdit creare il testo sottolineato e copiare e incollare nella casella di testo in XCode


Espandendo la risposta di @Nick H247, ho riscontrato un problema in cui inizialmente la sottolineatura non veniva ridisegnata quando il pulsante veniva ridimensionato a rotazione; questo può essere risolto impostando il tuo pulsante per ridisegnarlo in questo modo:

myButton.contentMode = UIViewContentModeRedraw; 

Ciò obbliga il pulsante a ridisegnare quando i limiti cambiano.

In secondo luogo, il codice originale presupponeva che avessi solo 1 riga di testo nel pulsante (il mio pulsante si avvolge su 2 righe alla rotazione) e la sottolineatura appare solo sull'ultima riga di testo. Il codice drawRect può essere modificato per calcolare innanzitutto il numero di righe nel pulsante, quindi inserire una sottolineatura su ogni riga anziché solo il fondo, in questo modo:

 - (void) drawRect:(CGRect)rect {
CGRect textRect = self.titleLabel.frame;

// need to put the line at top of descenders (negative value)
CGFloat descender = self.titleLabel.font.descender;

CGContextRef contextRef = UIGraphicsGetCurrentContext();

// set to same colour as text
CGContextSetStrokeColorWithColor(contextRef, self.titleLabel.textColor.CGColor);

CGSize labelSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font
                            constrainedToSize:self.titleLabel.frame.size
                                lineBreakMode:UILineBreakModeWordWrap];

CGSize labelSizeNoWrap = [self.titleLabel.text sizeWithFont:self.titleLabel.font forWidth:self.titleLabel.frame.size.width lineBreakMode:UILineBreakModeMiddleTruncation ];

int numberOfLines = abs(labelSize.height/labelSizeNoWrap.height);

for(int i = 1; i<=numberOfLines;i++) {
 //        Original code
 //        CGContextMoveToPoint(contextRef, textRect.origin.x, textRect.origin.y + textRect.size.height + descender + PADDING);
 //        
 //        CGContextAddLineToPoint(contextRef, textRect.origin.x + textRect.size.width, textRect.origin.y + textRect.size.height + descender);

    CGContextMoveToPoint(contextRef, textRect.origin.x, textRect.origin.y + (labelSizeNoWrap.height*i) + descender + PADDING);

    CGContextAddLineToPoint(contextRef, textRect.origin.x + textRect.size.width, textRect.origin.y + (labelSizeNoWrap.height*i) + descender);

    CGContextClosePath(contextRef);

    CGContextDrawPath(contextRef, kCGPathStroke);

}


}

Spero che questo codice aiuti qualcun altro!


Da iOS6 è ora possibile utilizzare una NSAttributedString per eseguire la sottolineatura (e qualsiasi altra funzione di supporto per le stringhe attribuita) in un modo molto più flessibile:

NSMutableAttributedString *commentString = [[NSMutableAttributedString alloc] initWithString:@"The Quick Brown Fox"];

[commentString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(0, [commentString length])];

[button setAttributedTitle:commentString forState:UIControlStateNormal];

Nota: ha aggiunto questo come un'altra risposta, in quanto è una soluzione totalmente diversa dalla mia precedente.

Modifica: stranamente (almeno in iOS8) devi sottolineare il primo carattere altrimenti non funziona!

così come una soluzione, imposta il primo carattere sottolineato con colore chiaro!

    // underline Terms and condidtions
    NSMutableAttributedString* tncString = [[NSMutableAttributedString alloc] initWithString:@"View Terms and Conditions"];

    // workaround for bug in UIButton - first char needs to be underlined for some reason!
    [tncString addAttribute:NSUnderlineStyleAttributeName
                      value:@(NSUnderlineStyleSingle)
                      range:(NSRange){0,1}];
    [tncString addAttribute:NSUnderlineColorAttributeName value:[UIColor clearColor] range:NSMakeRange(0, 1)];


    [tncString addAttribute:NSUnderlineStyleAttributeName
                      value:@(NSUnderlineStyleSingle)
                      range:(NSRange){5,[tncString length] - 5}];

    [tncBtn setAttributedTitle:tncString forState:UIControlStateNormal];

Puoi farlo nel generatore di interfaccia stesso.

  1. Seleziona l'ispettore degli attributi
  2. Cambia il tipo di titolo da semplice ad attribuito

  1. Imposta la dimensione del carattere e l'allineamento del testo appropriati

  1. Quindi seleziona il testo del titolo e imposta il carattere come sottolineato


Tutti i suggerimenti di cui sopra utilizzano %s segnaposto per argomento. Ti consiglierò di utilizzare %B perché %s formattazione di %s conserva nuove righe e il messaggio di commit di più righe appare schiacciato.

git log --pretty=format:"%h%x09%an%x09%ai%x09%B"




text formatting uibutton