简体   繁体   中英

Change attributed String dynamically

I have a TableViewCell in which I have a clickable textView :

let linkTextView: UITextView = {
    let v = UITextView()
    v.backgroundColor = .clear
    v.textAlignment = .left
    v.isScrollEnabled = false
    let padding = v.textContainer.lineFragmentPadding
    v.textContainerInset =  UIEdgeInsets(top: 0, left: -padding, bottom: 0, right: -padding)
    v.tintColor = .darkCustom
    v.isEditable = false
    v.isSelectable = true
    v.translatesAutoresizingMaskIntoConstraints = false
    return v
}()
let interactableText = NSMutableAttributedString(string: "Link öffnen")

In Cell I also have these two functions to style it and make it clickable :

func setupTextView(){
    interactableText.addAttributes([.underlineStyle: NSUnderlineStyle.single.rawValue,
                                    NSAttributedString.Key.font: UIFont(name: "AvenirNext-Medium", size: 15)!,
                                    NSAttributedString.Key.underlineColor: UIColor.darkCustom],
                                   range: NSRange(location: 0, length: interactableText.length))
    
    interactableText.addAttribute(NSAttributedString.Key.link,
                                  value: "https://www.google.de/?hl=de",
                                  range: NSRange(location: 0, length: interactableText.length))
}

func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool {
    self.linkTappedCallback!(URL)
    return false
}

This setup works. However it's not what I really want. I would like to be able to change the value of the link for each cell . I tried it like this in cellForRowAt :

    print(currentWish.link)
    cell.interactableText.addAttribute(NSAttributedString.Key.link,
                                       value: currentWish.link,
                                       range: NSRange(location: 0, length: cell.interactableText.length))

But when having it like this and dont set the link inside Cell the textView is no longer clickable. What am I missing here?

With the help of @elarcoiris I am now using this function and it works exactly the way I want it to:

extension UITextView {
func hyperLink(originalText: String, hyperLink: String, urlString: String) {

    let style = NSMutableParagraphStyle()
    style.alignment = .left

    let attributedOriginalText = NSMutableAttributedString(string: originalText)
    let linkRange = attributedOriginalText.mutableString.range(of: hyperLink)
    let fullRange = NSMakeRange(0, attributedOriginalText.length)
    attributedOriginalText.addAttribute(NSAttributedString.Key.link, value: urlString, range: linkRange)
    attributedOriginalText.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: fullRange)
    attributedOriginalText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.darkCustom, range: fullRange)
    attributedOriginalText.addAttribute(NSAttributedString.Key.underlineColor, value: UIColor.darkCustom, range: fullRange)
    attributedOriginalText.addAttribute(NSAttributedString.Key.font, value: UIFont(name: "AvenirNext-Medium", size: 15)!, range: fullRange)

    self.linkTextAttributes = [
        kCTForegroundColorAttributeName: UIColor.darkCustom,
        kCTUnderlineStyleAttributeName: NSUnderlineStyle.single.rawValue,
        ] as [NSAttributedString.Key : Any]

    self.attributedText = attributedOriginalText
}
}

Usage in cellForRowAt :

let cell = tableView.dequeueReusableCell(withIdentifier: WhishCell.reuseID, for: indexPath) as! WhishCell

cell.linkTextView.hyperLink(originalText: "Link öffnen", hyperLink: "Link öffnen", urlString: currentWish.link)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM