How to display HTML in UILabel and 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.
Offline Transcription: Fast, privacy-focus way to transcribe audio, video, and podcast files. No data leaves your Mac.
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.
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
}
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.
Offline Transcription: Fast, privacy-focus way to transcribe audio, video, and podcast files. No data leaves your Mac.
Related Resources
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 ShareHow 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.
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.