动态更改属性字符串
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
更改 link
的 value
。我在 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)
我有一个 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
更改 link
的 value
。我在 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)