mikalooch
mikalooch

Reputation: 91

Multiple Hyperlinks in UITextView : Underlined and Bold, Bold Not working

I have this code from a post on SO, I cannot find the original link, so I do deeply apologize.

Essentially, this code works for everything I need to do in a UITextView, multiple links with underline. However, when I try to add the Bold attribute, I am unable to get that to work.

import UIKit

extension UITextView {

  func buildLink(originalText: String, hyperLinks: [String: String]) {
    
    let style = NSMutableParagraphStyle()
    style.alignment = .left
    let attributedOriginalText = NSMutableAttributedString(string: originalText)

    for (hyperLink, urlString) in hyperLinks {
        let linkRange = attributedOriginalText.mutableString.range(of: hyperLink)
        let fullRange = NSRange(location: 0, length: attributedOriginalText.length)
        attributedOriginalText.addAttribute(.font, value: UIFont(name: "RobotoCondensed-Bold", size: 12.0)!, range: linkRange) /// this is the non functioning line
        attributedOriginalText.addAttribute(NSAttributedString.Key.link, value: urlString, range: linkRange)
        attributedOriginalText.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: fullRange)
        attributedOriginalText.addAttribute(NSAttributedString.Key.font, value: UIFont(name: "RobotoCondensed-Regular", size 12.0)!, range: fullRange)
        attributedOriginalText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.darkText, range: fullRange)
    }

    self.linkTextAttributes = [
        NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
    ]
    self.attributedText = attributedOriginalText
  }
}

If I also put the bold attribute in the linkTextAttributes array, it also doesn't work.

scratching my head on this.

Upvotes: 2

Views: 535

Answers (1)

Tarun Tyagi
Tarun Tyagi

Reputation: 10092

The problem is that you are applying the regular (NOT BOLD) text style to fullRange AFTER the bold has been applied to the linkRange.

for (hyperLink, urlString) in hyperLinks {
    let linkRange = attributedOriginalText.mutableString.range(of: hyperLink)
    let fullRange = NSRange(location: 0, length: attributedOriginalText.length)

    /// Here the correct attribute is applied for linkRange
    attributedOriginalText.addAttribute(.font, value: UIFont(name: "RobotoCondensed-Bold", size: 12.0)!, range: linkRange) /// this is the non functioning line
    attributedOriginalText.addAttribute(NSAttributedString.Key.link, value: urlString, range: linkRange)
    
    attributedOriginalText.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: fullRange)
    
    /// Here what was done correctly above gets overwritten
    attributedOriginalText.addAttribute(NSAttributedString.Key.font, value: UIFont(name: "RobotoCondensed-Regular", size 12.0)!, range: fullRange)
    attributedOriginalText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.darkText, range: fullRange)
}

This can be simplified to following -

let attributedOriginalText = NSMutableAttributedString(string: originalText)

/// Apply the normal text style to whole string at once
let fullRange = NSRange(location: 0, length: attributedOriginalText.length)
attributedOriginalText.addAttribute(.paragraphStyle, value: style, range: fullRange)
attributedOriginalText.addAttribute(.font, value: UIFont(name: "RobotoCondensed-Regular", size 12.0)!, range: fullRange)
attributedOriginalText.addAttribute(.foregroundColor, value: UIColor.darkText, range: fullRange)

/// Apply the link attributes at specified link ranges
for (hyperLink, urlString) in hyperLinks {
    let linkRange = attributedOriginalText.mutableString.range(of: hyperLink)
    attributedOriginalText.addAttribute(.font, value: UIFont(name: "RobotoCondensed-Bold", size: 12.0)!, range: linkRange)
    attributedOriginalText.addAttribute(.link, value: urlString, range: linkRange)    
}

Upvotes: 3

Related Questions