3

Trying to display a ASTextNode (same as UILabel from AsyncDisplayKit) to display an html text. I simply have to set the label's attributed text.

There is how i work my string :

Using this extension i transform the HTML text into a NSAttributedString :

extension String {
    var html2AttributedString: NSAttributedString? {
        guard let data = data(using: .utf8) else { return nil }
        do {
            return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription)
            return  nil
        }
    }
    var html2String: String {
        return html2AttributedString?.string ?? ""
    }
}

Then i set my label details :

 self.displayContent = NSMutableAttributedString(attributedString: content.html2AttributedString!)
 self.displayContent?.addAttribute(NSFontAttributeName, value: UIFont.fontMainFeedContentFont(), range: NSRange.init(location: 0, length: self.displayContent!.length))

So i have my label with my font and it's ok, problem is that i can't change the links colors of my label, it's a system blue that i do want.

Any idea how can i change the links' colors ?

Thanks.

user2206906
  • 1,310
  • 2
  • 13
  • 18

4 Answers4

3

I found an answer for this in Swift 4.0

termsAndPolicyTextView.linkTextAttributes = [
    NSAttributedString.Key.foregroundColor: UIColor.red
]

Full code: Note: I can't set multiple color in a single textView.

let attributedString = NSMutableAttributedString(string: termsAndPolicyText)

attributedString.addAttribute(
    NSAttributedString.Key.link,
    value: "https://google.co.in",
    range: (termsAndPolicyText as NSString).range(of: "Terms or service")
)

attributedString.addAttribute(
    NSAttributedString.Key.link,
    value: "https://google.co.in", // Todo set our terms and policy link here
    range: (termsAndPolicyText as NSString).range(of: "Privacy & Legal Policy")
)

attributedString.addAttributes(
    [NSAttributedString.Key.foregroundColor: UIColor.NMSTextColor(with: 0.6)],
    range: NSRange(location: 0, length: termsAndPolicyText.count)
)

termsAndPolicyTextView.linkTextAttributes = [
    NSAttributedString.Key.foregroundColor: UIColor.termstextViewTextColor()
]
termsAndPolicyTextView.attributedText = attributedString
termsAndPolicyTextView.textAlignment = .center
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Sarath
  • 343
  • 3
  • 12
2

Ok guys, i found an ugly way to do this.

After transforming the html text to an NSMutableAttributedString, i simply loop thought all attributes, when i see an "NSLink" attribute i simply add an attribute for the attribute's range :

self.myString!.enumerateAttributes(in: NSRange(0..<myString!.length), options: []) { (attributes, range, _) -> Void in
                for (attribute, object) in attributes {
                    if attribute == "NSLink" {
                        print("Attribute = \(attribute) -- \(object)")
                        self.myString?.addAttribute(NSForegroundColorAttributeName, value: StyleKit.color_blue_bright, range: range)
                        self.myString?.addAttribute(NSUnderlineColorAttributeName, value: UIColor.clear, range: range)
                    }
                }
            }
user2206906
  • 1,310
  • 2
  • 13
  • 18
0

The link color can be changed in the following way. The below example will demonstrate that:

let attributedText:NSMutableAttributedString = NSMutableAttributedString(string: "why?")
attributedText.addAttribute(NSUnderlineStyleAttributeName, value: NSUnderlineStyle.styleSingle, range: NSMakeRange(0, attributedText.length))
attributedText.addAttribute(NSUnderlineColorAttributeName, value: UIColor.black, range: NSMakeRange(0, attributedText.length))
attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: NSMakeRange(0, attributedText.length))

Also, you have to make the following changes to the UITextView that's displaying it.

textView.linkTextAttributes = [NSForegroundColorAttributeName : UIColor.black]

If you do not want to use UITextView to do this, you can simply use TTTAttributedLabel. It has linkAttributes and activeLinkAttributes property which you can use to achieve the desired behaviour without using UITextView.

Please let me know if it works or not. Feel free to suggest edits to make this better :)

KrishnaCA
  • 5,615
  • 1
  • 21
  • 31
  • it's not a textview that i use, i can't it's in tableview, i do not want to calculate the height, i'll try thank u – user2206906 Nov 30 '16 at 18:10
  • NSUnderlineStyleAttributeName simply underline the link, i want to change the text color of the link. – user2206906 Nov 30 '16 at 18:24
  • 1
    I believe you already tried it using `attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: NSMakeRange(0, attributedText.length))`. It didn't work for me. Only `UITextView` has `linkTextAttributes` property, and that is the only way which doesn't use coretext – KrishnaCA Nov 30 '16 at 19:53
  • You can use `UITextView` in a tableView and make it non-editable. Otherwise, one of the ways to do it would be using `TTTAttributedLabel`. https://github.com/TTTAttributedLabel/TTTAttributedLabel – KrishnaCA Nov 30 '16 at 19:56
  • No i need to achieve 60 fps scrolling... No UITextView and size calculation, so looks like not possible ... Thanks. – user2206906 Dec 01 '16 at 08:06
  • By size calculation, I believe you are thinking about resizing `UITextView` when user types something in it. There is no need for size calculation. You can simply use an `UITextView` like `UILabel` by making it non editable. – KrishnaCA Dec 01 '16 at 08:42
  • No it's on a table view, cell's size are dynamic, i never said user's interaction were enabled. – user2206906 Dec 01 '16 at 09:16
  • So, are you using `UITableviewAutomaticDimension` or calculating height for each cell? – KrishnaCA Dec 01 '16 at 09:20
  • No i'm using AsyncDisplayKit from Facebook. No size calculation, size calculation & UI rendering appears on the background. No need to handle this and that's why it is so fast. – user2206906 Dec 01 '16 at 09:21
  • Ok. Thanks for the info :) – KrishnaCA Dec 01 '16 at 09:21
  • See my answer that i wrote, not the fatest solution but it works ! – user2206906 Dec 01 '16 at 09:21
-1

Links color is default of attributed string. Can be specified by using css.

extension String {
    var html2AttributedString: NSAttributedString? {
        let html = """

<style type="text/css">
a, a:link, a:visited {
    color: inherit !important;
}
</style>
""" + self
        guard let data = html.data(using: .utf8) else { return nil }
        ...