Подчеркивая текст в UIButton - PullRequest
       78

Подчеркивая текст в UIButton

133 голосов
/ 13 апреля 2010

Кто-нибудь может подсказать, как подчеркнуть название UIButton? У меня есть пользовательский UIButton, и я хочу, чтобы заголовок был подчеркнут, но Интерфейсный Разработчик не предоставляет никакой возможности сделать это.

В Интерфейсном Разработчике, когда вы выбираете параметр «Шрифт» для кнопки, он предоставляет возможность выбрать «Нет», «Одиночный», «Двойной», «Цветной», но ни один из них не обеспечивает каких-либо изменений в заголовке на кнопке.

Любая помощь приветствуется.

Ответы [ 17 ]

3 голосов
/ 19 февраля 2015

В быстром

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)}
3 голосов
/ 07 августа 2013

Расширяя ответ @Nick H247, я столкнулся с проблемой, когда во-первых, подчеркивание не перерисовывалось при изменении размера кнопки при повороте; это можно решить, установив для вашей кнопки перерисовку следующим образом:

myButton.contentMode = UIViewContentModeRedraw; 

Это заставляет кнопку перерисовываться при изменении границ.

Во-вторых, исходный код предполагал, что в кнопке была только 1 строка текста (моя кнопка оборачивается до 2 строк при вращении), а подчеркивание появляется только в последней строке текста. Код drawRect можно изменить, чтобы сначала рассчитать количество строк в кнопке, а затем поставить подчеркивание на каждой строке, а не только на нижней части, например:

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

}


}

Надеюсь, этот код поможет кому-то еще!

2 голосов
/ 11 марта 2015

ответ Ника H247, но Свифт:

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);
    }
}
2 голосов
/ 15 октября 2014

Я полагаю, что это ошибка в редакторе шрифтов в XCode.Если вы используете конструктор интерфейса, вам нужно изменить заголовок с Обычный на Атрибут, откройте TextEdit, создайте подчеркнутый текст и скопируйте и вставьте в текстовое поле в XCode

2 голосов
/ 15 февраля 2012

Как справится со случаем, когда мы будем держать нажатой подчеркнутую кнопку? В этом случае цвет текста кнопки изменяется в соответствии с выделенным цветом, но линия остается оригинального цвета. Допустим, если цвет текста кнопки в обычном состоянии черный, то ее подчеркивание также будет иметь черный цвет. Цвет кнопки выделен белым. Удерживая нажатой кнопку, цвет текста кнопки изменяется с черного на белый, но цвет подчеркивания остается черным.

1 голос
/ 13 июля 2017
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)
    }
1 голос
/ 15 июня 2017

Swift 3 версия для @ NickH247's ответа с пользовательским цветом подчеркивания, шириной линии и пропуском:

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")
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...