3

I am creating NSAttributedString by using html:

let htmlString = "<body style='padding-left:50px'><h1>Hello World</h1><div><a href=https://apple.com/offer/samsung-faq/>Click Here</a></div><p>This is a sample text</p><pre>This is also sample pre text</pre></body>"

And here i am setting it to UILabel by using extension method

someLabel.attributedText = htmlString.htmlToAttributedString

NSAttributedString Extension:

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

Here i want an callback method to detect link which is there in html string as anchor tag. How will i get an event on click and how can i get the url in that event callback ?

Please help...

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Brammanand Soni
  • 177
  • 1
  • 4
  • 12
  • Have you reviewed this answer: https://stackoverflow.com/questions/33658521/how-to-make-a-uilabel-clickable – AzrimZ Jun 21 '18 at 13:40
  • Don't use `UILabel` for that, use `UITextView`, that's what it's made for. See this session of WWDC (at ~2:40): https://developer.apple.com/videos/play/wwdc2018/221/ `UILabel` aren't made for "click ability", they are here for displaying text, that's all. – Larme Jun 21 '18 at 13:56
  • You can use `UITextView` and it has a delegate called `shouldInteractWith`, in which you can get the link. – iPeter Jun 21 '18 at 13:58

1 Answers1

8

Use UITextView instead of UILabel and it has a property to convert your text to hyperlink.

You will have to make your UIViewController confirm to UITextViewDelegate protocol and implement textView(_:shouldInteractWith:in:interaction:. your standard UITextView setup should look something like this, don't forget the delegate and dataDetectorTypes.

@IBOutlet weak var txtView: UITextView!
// make IBOutlet of UITextView

txtTest.delegate = self
txtTest.isUserInteractionEnabled = true // default: true
txtTest.isEditable = false // default: true
txtTest.isSelectable = true // default: true
txtTest.dataDetectorTypes = [.link]

UITextViewDelegate method shouldInteractWithURL:

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
    print("Link Selected!")
    return true
}

HTML to NSAttributedString Extension:

extension String{
    func convertHtml() -> NSAttributedString{
        guard let data = data(using: .utf8) else { return NSAttributedString() }
        do{
            return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
        }catch{
            return NSAttributedString()
        }
    }
}

then you can use it like so.

let htmlString = "<body style='padding-left:50px'><h1>Hello World</h1><div><a href=https://apple.com/offer/samsung-faq/>Click Here</a></div><p>This is a sample text</p><pre>This is also sample pre text</pre></body>"

txtTest.attributedText = htmlString.convertHtml()
Govind Kumawat
  • 1,562
  • 1
  • 10
  • 17