在Swift中给按钮文本添加下划线

101

我有一个UIButton。在界面构建器中,我将其标题设置为'Attributed'。如何使用Swift代码使其标题带有下划线?

@IBOutlet weak var myBtn: UIButton!

我创建了一个函数,它在这个按钮的touchUpInside事件中被调用:

var attributedString = NSMutableAttributedString(string:"new text")
    var attrs = [
        NSFontAttributeName : UIFont.systemFontOfSize(19.0),
        NSForegroundColorAttributeName : UIColor.redColor()
    ]
    var gString = NSMutableAttributedString(string:"g", attributes:attrs)
    attributedString.appendAttributedString(gString)

    myBtn.titleLabel?.attributedText = attributedString;

但是仍然没有结果。我还需要知道如何访问下划线属性。文本、大小和颜色保持不变。


谢谢,但出于某些原因不起作用,我还需要了解下划线属性。 - moonvader
14个回答

161

Swift 5 / Xcode 12/13

  @IBOutlet weak var myButton: UIButton!
   
  let yourAttributes: [NSAttributedString.Key: Any] = [
      .font: UIFont.systemFont(ofSize: 14),
      .foregroundColor: UIColor.blue,
      .underlineStyle: NSUnderlineStyle.single.rawValue
  ] // .double.rawValue, .thick.rawValue
         
  
  override func viewDidLoad() {
     super.viewDidLoad()
    
     let attributeString = NSMutableAttributedString(
        string: "Your button text",
        attributes: yourAttributes
     )
     myButton.setAttributedTitle(attributeString, for: .normal)
  }

Swift 4 / Xcode 9

  @IBOutlet weak var myButton: UIButton!
   
  let yourAttributes: [NSAttributedStringKey: Any] = [
      NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14),
      NSAttributedStringKey.foregroundColor: UIColor.blue,
      NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue
  ] // .styleDouble.rawValue, .styleThick.rawValue, .styleNone.rawValue             
  
  override func viewDidLoad() {
    super.viewDidLoad()
    
    let attributeString = NSMutableAttributedString(
      string: "Your button text",
      attributes: yourAttributes
    )
    myButton.setAttributedTitle(attributeString, for: .normal)
  }

Swift 3 / Xcode 8

  @IBOutlet weak var myButton: UIButton!

  let yourAttributes: [String: Any] = [
      NSFontAttributeName: UIFont.systemFont(ofSize: 14),
      NSForegroundColorAttributeName: UIColor.white,
      NSUnderlineStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue
  ] // .styleDouble.rawValue, .styleThick.rawValue, .styleNone.rawValue             

   override func viewDidLoad() {
      super.viewDidLoad()

      let attributeString = NSMutableAttributedString(
        string: "Your button text",
        attributes: yourAttributes
      )        
      myButton.setAttributedTitle(attributeString, for: .normal) 
    }

enter image description here


我在使用Swift 4时遇到了这个错误:无法将类型为 '[String : Any]' 的值转换为预期的参数类型 '[NSAttributedStringKey : Any]?'。 - Pavlos
在倒数第二行设置 let 会导致 Xcode 9.1 崩溃,供参考。 - Zack Shapiro
我认为在这种情况下,我们应该使用不可变的属性字符串,例如 let attributeString = NSAttributedString(string: "Your button text", attributes: yourAttributes)。 - RunesReader

103

这是你需要的,我刚刚测试过(至少在xCode 7 Beta中可行)。

@IBOutlet weak var yourButton: UIButton!

var attrs = [
NSFontAttributeName : UIFont.systemFontOfSize(19.0),
NSForegroundColorAttributeName : UIColor.redColor(),
NSUnderlineStyleAttributeName : 1]

var attributedString = NSMutableAttributedString(string:"")

override func viewDidLoad() {
  super.viewDidLoad()

  let buttonTitleStr = NSMutableAttributedString(string:"My Button", attributes:attrs)
  attributedString.appendAttributedString(buttonTitleStr)
  yourButton.setAttributedTitle(attributedString, forState: .Normal)
}

52

故事板: 如果你想要从故事板中下划线文本。

  • 选择按钮或标签标题为属性文字。
  • 选择想要下划线的文本范围。
  • 右键单击,选择字体,然后选择下划线。

输入图像说明


这是最简单的答案。请注意,您必须确保在属性检查器中更改“标题”的值从“普通”->“带属性”。 - iOS_Mouse
对于暗黑模式更改颜色,这不起作用。 - Anilkumar iOS - ReactNative
这仅适用于静态模式,不适用于动态模式。谢谢! - Sukh

36

如果您想在不使用继承的情况下完成此操作 -

Swift 3/4/5

// in swift 4 - switch NSUnderlineStyleAttributeName with NSAttributedStringKey.underlineStyle

extension UIButton {
    func underline() {
        guard let text = self.titleLabel?.text else { return }
        let attributedString = NSMutableAttributedString(string: text)
        //NSAttributedStringKey.foregroundColor : UIColor.blue
        attributedString.addAttribute(NSAttributedString.Key.underlineColor, value: self.titleColor(for: .normal)!, range: NSRange(location: 0, length: text.count))
        attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: self.titleColor(for: .normal)!, range: NSRange(location: 0, length: text.count))
        attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: text.count))
        self.setAttributedTitle(attributedString, for: .normal)
    }
}



extension UILabel {
    func underline() {
        if let textString = self.text {
            let attributedString = NSMutableAttributedString(string: textString)
            attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: attributedString.length - 1))
            attributedText = attributedString
        }
    }
}

20

根据之前的一些答案,我决定制作一个可以轻松实现到您的应用程序中的类。

Swift 4

import UIKit

class UnderlineTextButton: UIButton {

override func setTitle(_ title: String?, for state: UIControlState) {
    super.setTitle(title, for: .normal)
    self.setAttributedTitle(self.attributedString(), for: .normal)
}

private func attributedString() -> NSAttributedString? {
    let attributes : [NSAttributedStringKey : Any] = [
        NSAttributedStringKey.font : UIFont.systemFont(ofSize: 19.0),
        NSAttributedStringKey.foregroundColor : UIColor.red,
        NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue
    ]
    let attributedString = NSAttributedString(string: self.currentTitle!, attributes: attributes)
    return attributedString
  }
}

我在代码中这样调用它:button.setTitle(author, for: .normal)


15
谢谢您发布代码,不太清楚您是否知道如何创建带属性的字符串。这应该可以工作:
var attrs = [
    NSFontAttributeName : UIFont.systemFontOfSize(19.0),
    NSForegroundColorAttributeName : UIColor.redColor(),
    NSUnderlineStyleAttributeName : NSUnderlineStyle.StyleSingle.rawValue
]

Swift 4 版本:

var attrs : [NSAttributedStringKey : Any] = [
    NSAttributedStringKey.font : UIFont.systemFont(ofSize: 19.0),
    NSAttributedStringKey.foregroundColor : UIColor.red,
    NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue
]

当我添加NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle时,它停止构建。 - moonvader
抱歉 - 我在 ObjC 和 Swift 之间混淆了一些东西。你需要使用 .rawValue。 - Glorfindel
我不知道为什么,但按钮标签没有改变。 - moonvader
@moonvader 当处理按钮时,您不能直接访问 titleLabel 来更改标签;相反,您必须使用 button.setAttributedTitle(attributedString, forState: .Normal) - Nathaniel

12

@ShlomoKoppelSwift 4.2 中的回答

extension UIButton {
    func underline() {
        guard let text = self.titleLabel?.text else { return }
        let attributedString = NSMutableAttributedString(string: text)
        //NSAttributedStringKey.foregroundColor : UIColor.blue
        attributedString.addAttribute(NSAttributedString.Key.underlineColor, value: self.titleColor(for: .normal)!, range: NSRange(location: 0, length: text.count))
        attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: self.titleColor(for: .normal)!, range: NSRange(location: 0, length: text.count))
        attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: text.count))
        self.setAttributedTitle(attributedString, for: .normal)
    }
}



extension UILabel {
    func underlineMyText() {
        if let textString = self.text {
            let attributedString = NSMutableAttributedString(string: textString)
            attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: attributedString.length - 1))
            attributedText = attributedString
        }
    }
}

8

在故事板上完成以下步骤(Xcode 9.1):

  1. 选择视图中的按钮对象。
  2. 打开字体设置。

enter image description here

  1. 选择单下划线。

enter image description here

  1. 输入您的文本,按[Enter]键。

1
如果计算机上没有安装字体,则此选项无效。如果您已向项目添加自定义字体但本地未安装该字体,则该字体不会显示在可用选项中。 - B-Rad

8

@shlomo-koppel的按钮标题修改答案的修改版,如果您以编程方式设置/更改按钮标题(例如在我的情况下,我使用本地化),则它将起作用。

extension UIButton {
    func underline() {
        guard let text = self.currentTitle else { return }
        let attributedString = NSMutableAttributedString(string: text)
        attributedString.addAttribute(NSAttributedString.Key.underlineColor, value: self.titleColor(for: .normal)!, range: NSRange(location: 0, length: text.count))
        attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: self.titleColor(for: .normal)!, range: NSRange(location: 0, length: text.count))
        attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: text.count))
        self.setAttributedTitle(attributedString, for: .normal)
    }
}

8
  • Swift 5.2.4
  • Xcode 11.5
let attributes: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.underlineStyle: 1,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 13),
NSAttributedString.Key.foregroundColor: UIColor.systemGray3
]

let attributedString = NSMutableAttributedString(string: "Text here", attributes: attributes)
button.setAttributedTitle(NSAttributedString(attributedString: attributedString), for: .normal)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接