Sharmin Khan
Sharmin Khan

Reputation: 317

swift: The HTML data converted to NSAttributed string doesn't make the links clickable in label

I have a text in HTML format. I am using the property of NSAttributed string to parse it. It pareses the text nicely and displays on the label. However, the parsing of the anchor tag doesn't make the link clickable. This is the following code that I am using for parsing.

extension String {
var htmlToAttributedString: NSAttributedString? {
    guard let data = data(using: .utf8) else { return NSAttributedString() }
    do {
        return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
    } catch {
        return NSAttributedString()
    }
}
var htmlToString: String {
    return htmlToAttributedString?.string ?? ""
}

When I run the app and give the value to the label as:

text = "<p>This is <a href=\"http://www.google.com\">Google Home</a></p>"
simpleTextLabel.attributedText = text.htmlToAttributedString

The output on the iOS App looks like following but nothing happens on clicking :

This is Google Home.

How can I make it open in safari?

Upvotes: 1

Views: 1831

Answers (1)

Larme
Larme

Reputation: 26006

From your line:

simpleTextLabel.attributedText = text.htmlToAttributedString

We can assume that simpleTextLabel is a UILabel.

It's basic behavior from a UILabel to not be "interactable". You can add a tap gesture on it, but it transform it as a UIButton.

There are some tricks to make it possible with a UILabel, find where exactly it has been tapped, check if there is a link, etc. Looking for "UILabel Clickable": Create tap-able "links" in the NSAttributedString of a UILabel? etc. There are even a few third party libs.

I (in my humble opinion) consider it as a "hack".

There is a good WWDC 2018 Session: TextKit Best Practices. At 2:34, it explains that if you need to interact with a shown text, prefers UITextView over UILabel.

There is a UITextViewDelegate method just for that: textView(_:shouldInteractWith:in:interaction:)

Note that there a small differences in the rendering of a UITextView and a UILabel. If you superpose them, they won't have the same "start point", the layout is a little different. However, with small changes, it can be the same (for instance: How can I make a UITextView layout text the same as a UILabel?).

Note also that according to the small modifications of a UITextView into a UILabel visual rendering, the user won't notice the difference (and that's in fact what matters, beside that using native methods of the UITextView/UITextViewDelegate make it easily understandable afterwards by another developer, or in a few months if you need to do a small modification).

Upvotes: 2

Related Questions