How to display HTML in UILabel and UITextView

⋅ 4 min read ⋅ UIKit HTML UILabel UITextView

Table of Contents

When you work with an API, there would be a time when your backend wants to control a text style. HTML is the most common format for this kind of job. Do you know that WKWebView is not the only way to present HTML string? You can render HTML string directly on UILabel and UITextView.

HTML String

A backend might return a response with something like this:

"This is a <b>bold</b> text."

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Convert to NSAttributedString

To render this text properly in UILabel or UITextView, you need to convert it to NSAttributedString. NSAttributedString has built-in support for this conversion.

First, we need to convert HTML string to Data.

let htmlString = "This is a <b>bold</b> text."
let data = htmlString.data(using: .utf8)!

Then we initialize NSAttributedString with the data and documentType option to .html.

let attributedString = try? NSAttributedString(
data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil)

After you get an attributed string, you can set it to UILabel or UITextView.

label.attributedText = attributedString

The result is quite ugly, as you might be expected.

Default style for html string
Default style for html string

Extension

Before we fix the style problem, let's create an extension out of this.

extension String {
func htmlAttributedString() -> NSAttributedString? {
guard let data = self.data(using: .utf8) else {
return nil
}

return try? NSAttributedString(
data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil
)
}
}

Now, we can use it like this.

let htmlString = "This is a <b>bold</b> text."
label.attributedText = htmlString.htmlAttributedString()

Apply a style

Since we are dealing with HTML, we can use CSS to apply a style to our attributed string. Simply create HTML boilerplate string and interpolate our content inside a body tag.

func htmlAttributedString() -> NSAttributedString? {
let htmlTemplate = """
<!doctype html>
<html>
<head>
<style>
body {
font-family: -apple-system;
font-size: 24px;
}
</style>
</head>
<body>
\(self)
</body>
</html>
"""


guard let data = htmlTemplate.data(using: .utf8) else {
return nil
}

guard let attributedString = try? NSAttributedString(
data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil
) else {
return nil
}

return attributedString
}
Attributed string with CSS as a style
Attributed string with CSS as a style

Parameterize

You can make our extension accept parameters of size and color for the ease of use.

extension String {
func htmlAttributedString(size: CGFloat, color: UIColor) -> NSAttributedString? {
let htmlTemplate = """
<!doctype html>
<html>
<head>
<style>
body {
color: \(color.hexString!);
font-family: -apple-system;
font-size: \(size)px;
}
</style>
</head>
<body>
\(self)
</body>
</html>
"""


guard let data = htmlTemplate.data(using: .utf8) else {
return nil
}

guard let attributedString = try? NSAttributedString(
data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil
) else {
return nil
}

return attributedString
}
}

extension UIColor {
var hexString:String? {
if let components = self.cgColor.components {
let r = components[0]
let g = components[1]
let b = components[2]
return String(format: "#%02x%02x%02x", (Int)(r * 255), (Int)(g * 255), (Int)(b * 255))
}
return nil
}
}

You can use it like this:

label.attributedText = htmlString.htmlAttributedString2(size: 18, color: .systemPink)

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Read more article about UIKit, HTML, UILabel, UITextView, or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
How to remove text from a navigation bar back button

There are a lot of hacky ways to modify or remove a back button title. This tip will show you how to do it properly.

Next
Memberwise Initializers for Structure Types

Struct is one of the basic building blocks in your app. Today I'm going to share some tips about memberwise Initializers.

← Home