1

I have a textView that allow user to enter NSAttributedString, convert into html string and then store into database. I also have code to convert the html string back and display in textView for editing. The conversion codes I have are

extension String {
    func htmlAttributedString() -> NSAttributedString? {
        guard let data = self.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil }
        guard let html = try? NSMutableAttributedString(
            data: data,
            options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
            documentAttributes: nil) else { return nil }
        return html
    }
}

extension NSAttributedString {
    func htmlString() -> String? {
        let documentAttributes = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType]
        do {
            let htmlData = try self.data(from: NSMakeRange(0, self.length), documentAttributes:documentAttributes)
            if let htmlString = String(data:htmlData, encoding:String.Encoding.utf8) { return htmlString }
        }
        catch {}
        return nil
    }
}

However the problem is that every time when I save and display the string, all font size increases. For example, I have a html string

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title></title>
<meta name="Generator" content="Cocoa HTML Writer">
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 17.0px '.SF UI Text'; color: #000000}
span.s1 {font-family: '.SFUIText'; font-weight: normal; font-style: normal; font-size: 17.00pt}
</style>
</head>
<body>
<p class="p1"><span class="s1">text</span></p>
</body>
</html>

After I convert it into NSAttributedString and back again, everything else are the same but the css lines are changed to this.

<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; line-height: 28.0px; font: 22.7px '.SF UI Text'; color: #000000; -webkit-text-stroke: #000000}
span.s1 {font-family: '.SFUIText'; font-weight: normal; font-style: normal; font-size: 22.67pt; font-kerning: none}
</style>

Am I missing anything? Any helps are appreciated!

Fangming
  • 24,551
  • 6
  • 100
  • 90
  • 1
    see https://stackoverflow.com/questions/20992950/ios7-font-size-change-when-create-nsattributedstring-from-html – Surya Subenthiran Jun 16 '17 at 14:00
  • 2
    https://stackoverflow.com/questions/28441486/html-to-nsattributedstring-and-nsattributedstring-to-html NSAttributedString seems to be messing points & px sizes. – Larme Jun 16 '17 at 14:04

2 Answers2

5

Try this method I found from some help and then converted to Swift 3:

func newAttrSize(blockQuote: NSAttributedString) -> NSAttributedString
{
    let yourAttrStr = NSMutableAttributedString(attributedString: blockQuote)
    yourAttrStr.enumerateAttribute(.font, in: NSMakeRange(0, yourAttrStr.length), options: .init(rawValue: 0)) {
        (value, range, stop) in
        if let font = value as? UIFont {
            let resizedFont = font.withSize(font.pointSize * 0.75)
            yourAttrStr.addAttribute(.font, value: resizedFont, range: range)
        }
    }

    return yourAttrStr
}
Asfand Shabbir
  • 1,234
  • 13
  • 9
0

I got the same problem, the simple solution is you just convert to RTF format instead of HTML. It 's worked fine.

mrri
  • 83
  • 5