首页 文章

在UIButton中加下划线

提问于
浏览
130

任何人都可以建议如何强调UIButton的 Headers ?我有一个自定义类型的UIButton,我希望 Headers 有下划线,但Interface Builder没有提供任何选项 .

在Interface Builder中为按钮选择字体选项时,它提供了选择无,单,双,颜色的选项,但这些选项都不会对按钮上的 Headers 进行任何更改 .

任何帮助赞赏 .

17 回答

  • 19

    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
    
  • 78

    要使用界面构建器加下划线,必须:

    • 将其更改为属性

    • 突出显示“属性”检查器中的文本

    • 右键单击,选择“字体”,然后选择“下划线”

    Underline using IB

    Video someone else made https://www.youtube.com/watch?v=5-ZnV3jQd9I

  • 351

    从iOS6开始,现在可以使用NSAttributedString以更灵活的方式执行下划线(以及其他任何归因于字符串支持的内容):

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

    注意:将此添加为另一个答案 - 因为它与我之前的解决方案完全不同 .

    Edit: 奇怪(至少在iOS8中)你必须为第一个字符加下划线,否则它不起作用!

    所以作为一种解决方法,将第一个char设置为带有明确颜色的下划线!

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

    您可以在界面构建器本身中执行此操作 .

    • 选择属性检查器

    • 将 Headers 类型从普通更改为属性

    enter image description here

    • 设置适当的字体大小和文本对齐方式

    enter image description here

    • 然后选择 Headers 文本并将字体设置为带下划线

    enter image description here

  • 27

    使用属性字符串非常简单

    创建具有set属性的字典并应用于属性字符串 . 然后,您可以将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];
    
  • 2

    这是我的功能,适用于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)
        }
    }
    
  • 33

    尼克的答案是一个很好的,快速的方法来做到这一点 .

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

    如果您的按钮 Headers 在文本下方有阴影,则Nick的回答不会考虑:

    enter image description here

    但你可以将下划线向下移动阴影的高度,如下所示:

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

    然后你会得到这样的东西:

    enter image description here

  • 125

    对于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)
        }
    }
    
  • 2
    // 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];
    }
    
  • 1

    扩展了@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);
    
    }
    
    
    }
    

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

  • 13

    在迅速

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

    当按下加下划线的按钮时,如何处理案例?在这种情况下,按钮的文本颜色会根据突出显示的颜色而改变,但线条保留原始颜色 . 假设正常状态下的按钮文字颜色是黑色,那么它的下划线也会有黑色 . 按钮的突出显示颜色为白色 . 按住按钮可将按钮文本颜色从黑色更改为白色,但下划线颜色保持黑色 .

  • 3

    我相信这是XCode中字体编辑器中的一些错误 . 如果使用界面构建器,则必须将 Headers 从Plain更改为Attributed,打开TextEdit创建带下划线的文本并将其复制粘贴到XCode中的文本框

  • 2

    尼克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

    You can use this code to add underline with spacing in button.

    • 当我尝试从界面构建器中绘制下划线时 . 它看起来像下面的图像 .

    1 - Interface builder reference

    • 使用下面的代码后,我按照自己的意愿实现了结果 .

    2 - using described code

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

    用于@NickH247's的Swift 3版本,自定义下划线颜色,线宽和间隙:

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

相关问题