动态更改属性字符串

Change attributed String dynamically

我有一个 TableViewCell,其中有一个可点击的 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")

Cell中我也有这两个函数来设置样式和制作它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
}

此设置有效。然而,这不是我真正想要的。我希望能够为每个 cell 更改 linkvalue。我在 cellForRowAt:

中这样尝试过
    print(currentWish.link)
    cell.interactableText.addAttribute(NSAttributedString.Key.link,
                                       value: currentWish.link,
                                       range: NSRange(location: 0, length: cell.interactableText.length))

但是当它像这样并且不在 Cell 中设置 link 时,textView 不再可点击。我在这里错过了什么?

在@elarcoiris 的帮助下,我现在正在使用这个函数,它完全按照我想要的方式工作:

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
}
}

cellForRowAt中的用法:

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

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