在UIButton中加下划线文字

任何人都可以build议如何强调一个UIButton的标题? 我有一个自定义types的UIButton,我希望标题有下划线,但Interface Builder不提供任何选项。

在界面生成器中,当您为buttonselect字体选项时,它将提供选项来selectNone,Single,Double,Color,但这些都不会对button上的标题提供任何更改。

任何帮助赞赏。

只需要自己做这个:

UIUnderlinedButton.h

@interface UIUnderlinedButton : UIButton { } + (UIUnderlinedButton*) underlinedButton; @end 

UIUnderlinedButton.m

 @implementation UIUnderlinedButton + (UIUnderlinedButton*) underlinedButton { UIUnderlinedButton* button = [[UIUnderlinedButton alloc] init]; return [button autorelease]; } - (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); 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); } @end 

要使用界面生成器强调,必须:

  • 将其更改为归因
  • 突出显示“属性”检查器中的文本
  • 右键单击,select字体,然后下划线

使用IB下划线

其他人的video制作了 https://www.youtube.com/watch?v=5-ZnV3jQd9I

在iOS6中,现在可以使用NSAttributedString以更灵活的方式执行下划线(以及任何其他属性string支持):

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

注意:添加这个作为另一个答案 – 作为一个完全不同的解决scheme,我以前的一个。

编辑:奇怪(至less在iOS8中),你必须强调第一个字符,否则它不工作!

所以作为一个解决方法,设置清晰的颜色下划线的第一个字符!

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

归属string非常简单

创build具有设置属性的字典并应用于属性string。 然后,您可以将属性string设置为uibutton中的attibutedtitle或uilabel中的attributestext。

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

这是我的function,在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) } 

更新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) } } 

尼克的答案是一个伟大的,快速的方法来做到这一点。

我在drawRect添加了对阴影的支持。

尼克的答案没有考虑到,如果你的button标题有一个低于文字阴影:

在这里输入图像说明

但是你可以通过阴影的高度来移动下划线,如下所示:

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

那么你会得到这样的东西:

在这里输入图像说明

 // 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]; } 

对于Swift 3,可以使用以下扩展名:

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

通过@Nick H247扩展答案,我遇到了一个问题,首先下划线在buttonresize时不会重新绘制; 这可以通过设置button来重新绘制,如下所示:

 myButton.contentMode = UIViewContentModeRedraw; 

这会强制button在边界更改时重新绘制。

其次,原来的代码假设你只有1行文本的button(我的button包装到旋转2行),下划线只出现在文本的最后一行。 可以修改drawRect代码,首先计算button中的行数,然后在每一行上加一个下划线,而不仅仅是底部,如下所示:

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

希望这个代码可以帮助别人!

当我们按下一个button时,如何处理这个案例? 在这种情况下,button的文本颜色根据高亮显示的颜色而改变,但是线条保持原始颜色。 假设button正常状态下的文本颜色是黑色的,那么下划线也是黑色的。 button突出显示的颜色是白色的。 按下保持button将button文字颜色从黑色变为白色,但下划线颜色保持黑色。

我相信这是XCode字体编辑器中的一些错误。 如果使用界面构build器,则必须将标题从普通(Plain)更改为已分配(Attributed),打开文本编辑器(TextEdit)创build带下划线的文本,并复制粘贴到XCode中的文本框

迅速

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

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

您可以使用此代码在button中添加带下划线的下划线。

  • 当我试图从界面生成器中绘制下划线。 它看起来像下面的图像。

1 – 接口生成器参考

  • 在使用下面的代码后,我达到了我想要的结果。

2 – 使用描述的代码

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

Swift 3版本为@ NickH247的答案与自定义下划线的颜色,线宽和差距:

 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") } } 
 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. select属性检查器
  2. 将标题types从纯文本更改为归因

在这里输入图像说明

  1. 设置适当的字体大小和文本alignment

在这里输入图像说明

  1. 然后select标题文本并将字体设置为带下划线

在这里输入图像说明