AjDev AjDev - 1 month ago 33
iOS Question

How to display text with HTML Tags in iOS 10 without using UIWebView (using swift)

Currently I am looking for a solution for below problem:

Problem:
I am receiving text with HTML tags like

<b></b>
,
<table><tr><td></td></tr></table>
etc.. as JSON response.
I need to render this data into UI for iOS(iphone) app and it should represent the data in desired way as If this data is mapped to a webview. i.e it should make the text
<b>bold</b>
and
<table><tr><td>**draw table**</table></tr></td>
as per the HTML tags.

I am using Xcode 8 with Swift 3.

Solution: ??

Answer

the approach is always the same: 1. turn the html into an attributedString 2. set that on the View/Control/TextView.. whatever

hope this helps. I use it all the time

import UIKit

public extension UIButton {
    public func setHTMLTitle(title: NSString?, for state: UIControlState) {
        guard let title = title else {
            setTitle(nil, for: state)
            return
        }

        guard let titleLabel = titleLabel else {
            setTitle(nil, for: state)
            return
        }

        if titleLabel.font == nil {
            titleLabel.font = UIFont.systemFont(ofSize:UIFont.systemFontSize)
        }

        var c = titleColor(for: state)
        if c == nil {
            c = UIColor.black
            setTitleColor(c, for: state)
        }

        setAttributedTitle(html(html: title, font: titleLabel.font, color: c!), for: state)
    }
}

public extension UILabel {
    public func setHTMLText(text: NSString?) {
        guard let text = text else {
            attributedText = nil
            return
        }

        if font == nil {
            font = UIFont.systemFont(ofSize:UIFont.systemFontSize)
        }
        if textColor == nil {
            textColor = UIColor.black
        }

        attributedText = html(html: text, font: font, color: textColor)
    }
}

public extension UITextView {
    public func setHTMLText(text: NSString?) {
        guard let text = text else {
            attributedText = nil
            return
        }

        if font == nil {
            font = UIFont.systemFont(ofSize:UIFont.systemFontSize)
        }
        if textColor == nil {
            textColor = UIColor.black
        }

        attributedText = html(html: text, font:font!, color:textColor!)
    }
}

//shared helpers

private func html(html:NSString, font:UIFont, color:UIColor) -> NSAttributedString {
    let colorName = colorToHexString(color: color)
    let fontName = font.fontName
    let fontSize = font.pointSize

    let style = "<style>body{color: \(colorName); font-family: '\(fontName)'; font-size:\(fontSize)px;}</style>"
    let htmlString = html.appending(style)
    let d = htmlString.data(using: String.Encoding.utf8)!

    let o = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType as AnyObject, NSCharacterEncodingDocumentAttribute: NSNumber(value: String.Encoding.utf8.rawValue) as AnyObject] as [String:AnyObject]

    do {
        let attrStr = try NSAttributedString(data:d, options:o, documentAttributes:nil)
        return attrStr
    }
    catch {
        return NSAttributedString(string: "")
    }
}

private func colorToHexString(color: UIColor) -> String {
    var r:CGFloat = 0
    var g:CGFloat = 0
    var b:CGFloat = 0
    var a:CGFloat = 0

    color.getRed(&r, green: &g, blue: &b, alpha: &a)

    let rgb:Int = (Int)(r*255)<<16 | (Int)(g*255)<<8 | (Int)(b*255)<<0

    return String(format:"#%06x", rgb)
}

***DISCLAIMER, this is part of my open source library DDUtils

Comments