49

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)
Jon Schneider
  • 25,758
  • 23
  • 142
  • 170
Martin Muldoon
  • 3,388
  • 4
  • 24
  • 55
  • 2
    Hope this help: https://stackoverflow.com/questions/24666515/how-do-i-make-an-attributed-string-using-swift – Amit Aug 30 '17 at 12:05
  • 1
    https://stackoverflow.com/questions/41412963/swift-change-font-on-an-html-string-that-has-its-own-styles this one. – Larme Aug 30 '17 at 15:21
  • @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 Aug 30 '17 at 21:54
  • 1
    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 Aug 31 '17 at 08:33

7 Answers7

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

Background Color

let myAttribute = [ NSBackgroundColorAttributeName: UIColor.yellow ]
pkamb
  • 33,281
  • 23
  • 160
  • 191
Vikas Rajput
  • 1,754
  • 1
  • 14
  • 26
  • 2
    What is different from: [https://stackoverflow.com/a/32269975/5575752](https://stackoverflow.com/a/32269975/5575752) ? Already suggested that answer in Question comment...please don't duplicate answers. – Ronak Chaniyara Aug 30 '17 at 12:29
  • if there is similar question ask before you must be provide a duplicate link or comment instead of copy of answer. Thanks – Nitin Gohel Aug 30 '17 at 13:43
  • Yes you! You should! You must! Thanks – vir us Aug 15 '18 at 12:16
24

In Swift you can use:

let stringWithAttribute = NSAttributedString(string: selectedFilter ?? "",
                                             attributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14.0)])
pkamb
  • 33,281
  • 23
  • 160
  • 191
Osman
  • 1,496
  • 18
  • 22
8

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!

Alan Steiman
  • 412
  • 1
  • 4
  • 14
4

Please Check this one

var attrString = NSAttributedString(string: "labelText", attributes: [NSForegroundColorAttributeName: UIColor.red, NSFontAttributeName: UIFont(name: "system", size: 12)])
label.attributedText = attrString
Community
  • 1
  • 1
Inder_iOS
  • 1,636
  • 1
  • 12
  • 20
4

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
1

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

let  attributes = [
   NSForegroundColorAttributeName: UIColor.black,
            ]
try NSAttributedString(string: "", attributes: attributes)
Sakshi
  • 1,060
  • 11
  • 25
  • Thanks. I getting the following error: Cannot convert value of type [String: NSObject] to expected argument type Autoreleasing unsafe pointer The error is pointing to the attributes variable I added as you suggested. – Martin Muldoon Aug 30 '17 at 12:53
  • which version of swift you are using? – Sakshi Aug 30 '17 at 12:54
0

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)
Nirav Kotecha
  • 2,493
  • 1
  • 12
  • 26