Created
November 6, 2019 13:38
-
-
Save amichnia/63ac8c0107773651ccbde3b127b77c63 to your computer and use it in GitHub Desktop.
Swift: Convert basic raw html string to attributed string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
extension String { | |
private var attributedStringOptions: [NSAttributedString.DocumentReadingOptionKey: Any] { | |
return [ | |
.documentType: NSAttributedString.DocumentType.html, | |
.characterEncoding: String.Encoding.utf8.rawValue | |
] | |
} | |
var wholeRange: NSRange { | |
return NSRange(location: 0, length: count) | |
} | |
var html2Attributed: NSAttributedString { | |
return attributedString() | |
} | |
func html2Attributed( | |
font: UIFont, | |
color: UIColor, | |
attributes: [NSAttributedString.Key: Any] = [:] | |
) -> NSAttributedString { | |
let base = attributedString(with: """ | |
html * { | |
font-size: \(font.pointSize)pt !important; | |
font-family: \(font.familyName), Helvetica !important; | |
color: \(color.hexString) !important; | |
} | |
""") | |
base.beginEditing() | |
base.replaceFonts(with: font) | |
base.addAttributes(attributes, range: base.string.wholeRange) | |
base.endEditing() | |
return base | |
} | |
private func attributedString(with style: String = "") -> NSMutableAttributedString { | |
let base = NSMutableAttributedString(string: self) | |
guard let data = "<style>\(style)</style>\(self)".data(using: .utf8) else { | |
return base | |
} | |
return (try? NSMutableAttributedString( | |
data: data, | |
options: attributedStringOptions, | |
documentAttributes: nil | |
)) ?? base | |
} | |
} | |
extension UIColor { | |
var hexString: String { | |
var r: CGFloat = 0 | |
var g: CGFloat = 0 | |
var b: CGFloat = 0 | |
getRed(&r, green: &g, blue: &b, alpha: nil) | |
let rgb: Int = (Int)(r * 255) << 16 | (Int)(g * 255) << 8 | (Int)(b * 255) << 0 | |
return NSString(format: "#%06x", rgb) as String | |
} | |
} | |
extension NSMutableAttributedString { | |
func replaceFonts(with font: UIFont) { | |
let descriptor = font.fontDescriptor | |
var changes: [NSRange: Any] = [:] | |
enumerateAttribute(.font, in: string.wholeRange, options: []) { foundFont, range, _ in | |
guard let traits = (foundFont as? UIFont)?.fontDescriptor.symbolicTraits else { | |
return | |
} | |
guard let adjustedDescriptor = descriptor.withSymbolicTraits(traits) else { | |
return | |
} | |
let newFont = UIFont(descriptor: adjustedDescriptor, size: font.pointSize) | |
changes[range] = newFont | |
} | |
changes.forEach { range, newValue in | |
removeAttribute(.font, range: range) | |
addAttribute(.font, value: newValue, range: range) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment