Underline button text in Swift

IosXcodeSwift

Ios Problem Overview


I have UIButton. In interface builder I set its title to be 'Attributed'. How can I make its title to be underlined from code in Swift?

@IBOutlet weak var myBtn: UIButton!

I created a function called on the touchUpInside event of this button:

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;

But still no result. Also I need to know how to access the underline attribute. Text, size and color stay the same.

Ios Solutions


Solution 1 - Ios

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

Solution 2 - Ios

Here you go, just tested it. (works in xCode 7 Beta at least)

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

Solution 3 - Ios

StoryBoard: If you want to Underline text from storyBoard.

  • Select button or label title as Attributed.
  • Select range of text which you want to underline.
  • Right click and choose Font then select underline.

enter image description here

Solution 4 - Ios

if you are looking for a way to do this without inheritance -

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

Solution 5 - Ios

Based on some of previous answers I decide to make a class that can be easy implemented into your apps

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

From code I call it on such a way button.setTitle(author, for: .normal)

Solution 6 - Ios

Thanks for posting your code, it wasn't clear that you knew how to create an attributed string at all.

This should work:

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

Swift 4 version:

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

Solution 7 - Ios

@ShlomoKoppel answer in Swift 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
        }
    }
}

Solution 8 - Ios

Here is done on the storyboard. (Xcode 9.1)

  1. Select the Button object in your view.
  2. Open Fonts Settings

enter image description here

  1. Select Single Underline

enter image description here

  1. Type your text, press [Enter]

Solution 9 - Ios

This is my solution. And to be honest you probably need this more than one place, so let's create an extension. This is swift 5.0 Cheers :)

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

And you can use it like this.

    override func viewDidLoad() {
     super.viewDidLoad()
     button.underline()
}

Solution 10 - Ios

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

Solution 11 - Ios

A modified version of @shlomo-koppel answer for button title, It will work if you set/change button title programmatically (like in my case I used localization)

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

Solution 12 - Ios

For swift 5

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

Solution 13 - Ios

Here you can add an underline and bold face too. You can just add an extention in your swift class file

Here is the extention (Swift 4 updated)

extension NSMutableAttributedString {
 @discardableResult func bold(_ text:String) -> NSMutableAttributedString {
      
      let attrs : [NSAttributedStringKey : Any] = [
        NSAttributedStringKey.font : UIFont(name: "Montserrat-Bold", size: 12)!,
        NSAttributedStringKey.foregroundColor : UIColor.white,
        NSAttributedStringKey.underlineStyle : NSUnderlineStyle.styleSingle.rawValue]
    let boldString = NSMutableAttributedString(string: text, attributes: attrs)
    self.append(boldString)
    return self
 }
 
 @discardableResult func normal(_ text:String)->NSMutableAttributedString {
      let attrs : [NSAttributedStringKey : Any] = [
        NSAttributedStringKey.font : UIFont(name: "Montserrat-Regular", size: 12)!,
        NSAttributedStringKey.foregroundColor : UIColor.white
    ]
    let normal =  NSAttributedString(string: text,  attributes:attrs)
    self.append(normal)
    return self
 }

}

You can use it like this:

let FormattedText = NSMutableAttributedString()
      FormattedText
           .normal("By signing in, you agree with our ")
           .bold("Terms of Service")

yourLabel.attributedText = FormattedText

and the Result will be display like this enter image description here

Solution 14 - Ios

May not be the best approach but I made an example to use it with a separated class and make only a one line call to get the text.

Here is my class:

import Foundation
import UIKit

enum AttributedTextsType {
    case underlined
    case bold
    case boldUnderlined
}

class AttributedTexts {
    private static func underlinedText(color: UIColor, size: CGFloat) -> [NSAttributedString.Key : Any] {
    let attrs = [
        NSAttributedString.Key.font : UIFont.systemFont(ofSize: size),
        NSAttributedString.Key.foregroundColor : color,
        NSAttributedString.Key.underlineStyle : 1] as [NSAttributedString.Key : Any]
    return attrs
    }

    private static func getAttibute(type: AttributedTextsType, color: UIColor, size: CGFloat) -> [NSAttributedString.Key : Any] {
        var attributes: [NSAttributedString.Key : Any]!
        switch type {
        case .underlined:
            attributes = AttributedTexts.underlinedText(color: color, size: size)
            break
        case .bold:
            attributes = AttributedTexts.underlinedText(color: color, size: size)
            break
        case .boldUnderlined:
            attributes = AttributedTexts.underlinedText(color: color, size: size)
            break
        }
        return attributes
    }

    static func set(string: String, color: UIColor, type: AttributedTextsType, size: CGFloat = 19.0) -> NSMutableAttributedString {
        let attributes = getAttibute(type: type, color: color, size: size)
        let attributedString = NSMutableAttributedString(string:"")
        let buttonTitleStr = NSMutableAttributedString(string: string, attributes: attributes)
        attributedString.append(buttonTitleStr)
        return attributedString
    }
}

Usage let attributedString = AttributedTexts.set(string: "Skip", color: .white, type: .underlined, size: 19.0)

Best regards

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmoonvaderView Question on Stackoverflow
Solution 1 - IosA.KantView Answer on Stackoverflow
Solution 2 - Ios36 By DesignView Answer on Stackoverflow
Solution 3 - IosSukhView Answer on Stackoverflow
Solution 4 - IosShlomo KoppelView Answer on Stackoverflow
Solution 5 - IosMax TymchiiView Answer on Stackoverflow
Solution 6 - IosGlorfindelView Answer on Stackoverflow
Solution 7 - IosKiran JasvaneeView Answer on Stackoverflow
Solution 8 - IosChong HannView Answer on Stackoverflow
Solution 9 - IostBugView Answer on Stackoverflow
Solution 10 - IoshectorsvillView Answer on Stackoverflow
Solution 11 - IosAshWinee DhakadView Answer on Stackoverflow
Solution 12 - IosTalha RasoolView Answer on Stackoverflow
Solution 13 - IosAzharhussain ShaikhView Answer on Stackoverflow
Solution 14 - IosAndres PaladinesView Answer on Stackoverflow