[text] Sottolineare il testo in UIButton


7 Answers

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

Question

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.




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




// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (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();
UIColor *colr;
// set to same colour as text
if (self.isHighlighted || self.isSelected) {
    colr=self.titleLabel.highlightedTextColor;
}
else{
    colr= self.titleLabel.textColor;
}
CGContextSetStrokeColorWithColor(contextRef, colr.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);
}
//Override this to change the underline color to highlighted color
-(void)setHighlighted:(BOOL)highlighted
{
[super setHighlighted:highlighted];
// [self setNeedsDisplay];
}



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




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")
    }
}



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!




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



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);
    }
}



Related