40
votes

Edit - This has been marked as duplicate, but as I state below, I am looking for a Swift solution. Everything I've found is written in Objective C.

I am trying to convert HTML into an NSAttributedString, but can't figure how to set the font style and size. All of the examples are in Objective C which I'm not skilled in. How can I set the font style/size to System 15 (as an example)

private func stringFromHtml(string: String) -> NSAttributedString? {
        do {
            let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
            if let d = data {
                let str = try NSAttributedString(data: d,
                                                 options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],                                                  documentAttributes: nil)
                return str
            }
        } catch {
        }
        return nil
    }

EDIT...... I've tried several ways. I can't get it to work. I'm now getting an error message: Type of expression is ambiguous without more context. It's pointing to the NSAttributedString I've tried the following:

let myAttribute = [ NSForegroundColorAttributeName: UIColor.blue ]
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
  if let d = data {
     let str = try NSAttributedString(data: d,
                       attributes: myAttribute,
                       options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
7
@Larme... I solved it using the extension example in the Link you provided. Sadly I still don't understand it. I believe I had to create an NSMutableAttributedString, whereas I was just trying to alter an Attributed String? Thanks! - Martin Muldoon
The thing is that attributes works like a dictionary (unicity of key for a given range). Bold, Font, Italic, and Font Size are inside the same one. So you need to iterate to modify one property of the font. The other solution is to modify the HTML before translating it. - Larme

7 Answers

56
votes
  let myString = "Swift Attributed String"
  let myAttribute = [ NSForegroundColorAttributeName: UIColor.blue ]
  let myAttrString = NSAttributedString(string: myString, attributes: myAttribute) 

  // set attributed text on a UILabel
  myLabel.attributedText = myAttrString

font

 let myAttribute = [ NSFontAttributeName: UIFont(name: "Chalkduster", size: 18.0)! ]

Shadow

let myShadow = NSShadow()
myShadow.shadowBlurRadius = 3
myShadow.shadowOffset = CGSize(width: 3, height: 3)
myShadow.shadowColor = UIColor.gray
let myAttribute = [ NSShadowAttributeName: myShadow ]

Underline

 let myAttribute = [ NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleSingle.rawValue ]

Textcolor

 let myAttribute = [ NSForegroundColorAttributeName: UIColor.blue ]

BackGroud Color

  let myAttribute = [ NSBackgroundColorAttributeName: UIColor.yellow ]
19
votes

Swift 4 You can use :

 let stringWithAttribute = NSAttributedString(string: selectedFilter ?? "",
                                                  attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14.0)])
6
votes

The only thing that worked for me is to wrap the HTML in a <span> and apply the style there:

let modifiedFontString = "<span style=\"font-family: Lato-Regular; font-size: 14; color: rgb(60, 60, 60)\">" + originalHTMLString + "</span>"

Try this extension:

extension String {

    var htmlToAttributedString: NSAttributedString? {
        guard let data = data(using: .utf8) else { return NSAttributedString() }
        do {
            return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
        } catch {
            return NSAttributedString()
        }
    }

    var htmlToString: String {
        return htmlToAttributedString?.string ?? ""
    }

    func convertToAttributedString() -> NSAttributedString? {
        let modifiedFontString = "<span style=\"font-family: Lato-Regular; font-size: 14; color: rgb(60, 60, 60)\">" + self + "</span>"
        return modifiedFontString.htmlToAttributedString
    }
}

And you use it like this:

someLabel.attributedString = someHTMLString.convertToAttributedString()

Hope it helps!

3
votes

Check this for swift 5:

extension String {
    func getAttributedString<T>(_ key: NSAttributedString.Key, value: T) -> NSAttributedString {
       let applyAttribute = [ key: T.self ]
       let attrString = NSAttributedString(string: self, attributes: applyAttribute)
       return attrString
    }
}

You can check more attributes styles here: https://developer.apple.com/documentation/foundation/nsattributedstring/key

USE

// Background Color
let attributedString = "YOUR_STRING".getAttributedString(.backgroundColor, value: UIColor.blue)

// Forground Color
let attributedString = "YOUR_STRING".getAttributedString(.foregroundColor, value: UIColor.red)

// Font
let attributedString = "YOUR_STRING".getAttributedString(.font, value: UIFont.boldSystemFont(ofSize: 15))

// Underline
let attributedString = "YOUR_STRING".getAttributedString(.underlineStyle, value: NSUnderlineStyle.single)

// Underline Color
let attributedString = "YOUR_STRING".getAttributedString(.underlineColor, value: UIColor.black)

    
// set attributed text on a UILabel
yourLabel.attributedText = attributedString
2
votes
var attrString = NSAttributedString(string: "labelText", attributes: [NSForegroundColorAttributeName: UIColor.red, NSFontAttributeName: UIFont(name: "system", size: 12)])
label.attributedText = attrString
1
votes

First you need to convert data to string then use this peice of code

let  attributes = [
   NSForegroundColorAttributeName: UIColor.black,
            ]
try NSAttributedString(string: "", attributes: attributes)
0
votes

you can set this way

let attribute: [String : Any] = [NSFontAttributeName: UIFont.systemFont(ofSize: UIFont.systemFontSize, weight: UIFontWeightThin),
    NSForegroundColorAttributeName: UIColor.red]

let attributedText = NSAttributedString(string: "Your String", attributes: attribute)