带有 2 个链接的 UITextView 属性文本,每个链接都有不同的颜色不起作用
UITextView Attributed text with 2 links, each with different colors not working
我想在属性字符串中显示 2 link,每个 link 具有不同的颜色。我不明白该怎么做。它总是只设置一种颜色。几天来我一直在为此苦苦挣扎,但仍然不知道如何让它发挥作用。有人知道吗?我可以设置两种颜色,但不能设置 links!所有 link 都是相同的颜色。
这是我的整个实现:(更新)
var checkIn = ""
var friends = ""
//MARK: Change Name Color / Font / Add a second LABEL into the same label
func setColorAndFontAttributesToNameAndCheckIn() {
let nameSurname = "\(postAddSetup.nameSurname.text!)"
checkIn = ""
friends = ""
if selectedFriends.count == 0 {
print("we have no friends...")
friends = ""
} else if selectedFriends.count == 1 {
print("we have only one friend...")
friends = ""
friends = " is with \(self.firstFriendToShow)"
} else if selectedFriends.count > 1 {
print("we have more than one friend...")
friends = ""
friends = " is with \(self.firstFriendToShow) and \(self.numberOfFriendsCount) more"
}
if checkIn == "" {
checkIn = ""
}
var string = postAddSetup.nameSurname.text
string = "\(nameSurname)\(friends)\(checkIn) "
let attributedString = NSMutableAttributedString(string: string!)
attributedString.addAttribute(NSFontAttributeName, value: UIFont.boldSystemFont(ofSize: 14), range: (string! as NSString).range(of: nameSurname))
attributedString.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 13), range: (string! as NSString).range(of: checkIn))
attributedString.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 13), range: (string! as NSString).range(of: friends))
attributedString.addLink("checkIn", linkColor: UIColor.darkGray, text: checkIn)
attributedString.addLink("tagFriends", linkColor: UIColor.red, text: friends)
//attributedString.addAttribute(NSLinkAttributeName, value: "checkIn", range: (string! as NSString).range(of: checkIn))
//attributedString.addAttribute(NSLinkAttributeName, value: "tagFriends", range: (string! as NSString).range(of: friends))
//postAddSetup.nameSurname.linkTextAttributes = [NSForegroundColorAttributeName:UIColor.redIWorkOut(), NSFontAttributeName: UIFont.systemFont(ofSize: 13)]
//attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.darkGray, range: (string! as NSString).range(of: checkIn))
postAddSetup.nameSurname.attributedText = attributedString
print("atribute: \(attributedString)")
}
func string1Action() {
print("action for string 1...")
}
func string2Action() {
print("action for string 2...")
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
if URL.absoluteString == "string1" {
string1Action()
} else if URL.absoluteString == "string2" {
string2Action()
}
return false
}
extension NSMutableAttributedString {
func addLink(_ link: String, linkColor: UIColor, text: String) {
let pattern = "(\(text))"
let regex = try! NSRegularExpression(pattern: pattern,
options: NSRegularExpression.Options(rawValue: 0))
let matchResults = regex.matches(in: self.string,
options: NSRegularExpression.MatchingOptions(rawValue: 0),
range: NSRange(location: 0, length: self.string.characters.count))
for result in matchResults {
self.addAttribute(NSLinkAttributeName, value: link, range: result.rangeAt(0))
self.addAttribute(NSForegroundColorAttributeName, value: linkColor, range: result.rangeAt(0))
}
}
}
我在一个项目中使用了这个 NSMutableAttributedString extension
改编自这个 Article.
使用 NSRegularExpression
您可以指定与 link 文本范围相匹配的相应颜色:
分机:
extension NSMutableAttributedString {
func addLink(_ link: String, linkColor: UIColor, text: String) {
let pattern = "(\(text))"
let regex = try! NSRegularExpression(pattern: pattern,
options: NSRegularExpression.Options(rawValue: 0))
let matchResults = regex.matches(in: self.string,
options: NSRegularExpression.MatchingOptions(rawValue: 0),
range: NSRange(location: 0, length: self.string.characters.count))
for result in matchResults {
self.addAttribute(NSLinkAttributeName, value: link, range: result.rangeAt(0))
self.addAttribute(NSForegroundColorAttributeName, value: linkColor, range: result.rangeAt(0))
}
}
}
编辑:
设置自定义 UITextView class 以使用此扩展并使用委托函数 shouldInteractWith url 可以模拟 UITextView 的超级link 逻辑:
class CustomTextView: UITextView {
private let linksAttributes = [NSLinkAttributeName]
override func awakeFromNib() {
super.awakeFromNib()
let tapGest = UITapGestureRecognizer(target: self, action: #selector(self.onTapAction))
self.addGestureRecognizer(tapGest)
}
@objc private func onTapAction(_ tapGest: UITapGestureRecognizer) {
let location = tapGest.location(in: self)
let charIndex = self.layoutManager.characterIndex(for: location, in: self.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
if charIndex < self.textStorage.length {
var range = NSMakeRange(0, 0)
for linkAttribute in linksAttributes {
if let link = self.attributedText.attribute(linkAttribute, at: charIndex, effectiveRange: &range) as? String {
guard let url = URL(string: link) else { return }
_ = self.delegate?.textView?(self, shouldInteractWith: url, in: range, interaction: .invokeDefaultAction)
}
}
}
}
}
使用方法:
attributedString.addLink(yourLinkUrl, linkColor: yourLinkColor, text: yourLinkText)
let textView = CustomTextView()
textView.attributedText = attributedString
我想在属性字符串中显示 2 link,每个 link 具有不同的颜色。我不明白该怎么做。它总是只设置一种颜色。几天来我一直在为此苦苦挣扎,但仍然不知道如何让它发挥作用。有人知道吗?我可以设置两种颜色,但不能设置 links!所有 link 都是相同的颜色。
这是我的整个实现:(更新)
var checkIn = ""
var friends = ""
//MARK: Change Name Color / Font / Add a second LABEL into the same label
func setColorAndFontAttributesToNameAndCheckIn() {
let nameSurname = "\(postAddSetup.nameSurname.text!)"
checkIn = ""
friends = ""
if selectedFriends.count == 0 {
print("we have no friends...")
friends = ""
} else if selectedFriends.count == 1 {
print("we have only one friend...")
friends = ""
friends = " is with \(self.firstFriendToShow)"
} else if selectedFriends.count > 1 {
print("we have more than one friend...")
friends = ""
friends = " is with \(self.firstFriendToShow) and \(self.numberOfFriendsCount) more"
}
if checkIn == "" {
checkIn = ""
}
var string = postAddSetup.nameSurname.text
string = "\(nameSurname)\(friends)\(checkIn) "
let attributedString = NSMutableAttributedString(string: string!)
attributedString.addAttribute(NSFontAttributeName, value: UIFont.boldSystemFont(ofSize: 14), range: (string! as NSString).range(of: nameSurname))
attributedString.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 13), range: (string! as NSString).range(of: checkIn))
attributedString.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 13), range: (string! as NSString).range(of: friends))
attributedString.addLink("checkIn", linkColor: UIColor.darkGray, text: checkIn)
attributedString.addLink("tagFriends", linkColor: UIColor.red, text: friends)
//attributedString.addAttribute(NSLinkAttributeName, value: "checkIn", range: (string! as NSString).range(of: checkIn))
//attributedString.addAttribute(NSLinkAttributeName, value: "tagFriends", range: (string! as NSString).range(of: friends))
//postAddSetup.nameSurname.linkTextAttributes = [NSForegroundColorAttributeName:UIColor.redIWorkOut(), NSFontAttributeName: UIFont.systemFont(ofSize: 13)]
//attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.darkGray, range: (string! as NSString).range(of: checkIn))
postAddSetup.nameSurname.attributedText = attributedString
print("atribute: \(attributedString)")
}
func string1Action() {
print("action for string 1...")
}
func string2Action() {
print("action for string 2...")
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
if URL.absoluteString == "string1" {
string1Action()
} else if URL.absoluteString == "string2" {
string2Action()
}
return false
}
extension NSMutableAttributedString {
func addLink(_ link: String, linkColor: UIColor, text: String) {
let pattern = "(\(text))"
let regex = try! NSRegularExpression(pattern: pattern,
options: NSRegularExpression.Options(rawValue: 0))
let matchResults = regex.matches(in: self.string,
options: NSRegularExpression.MatchingOptions(rawValue: 0),
range: NSRange(location: 0, length: self.string.characters.count))
for result in matchResults {
self.addAttribute(NSLinkAttributeName, value: link, range: result.rangeAt(0))
self.addAttribute(NSForegroundColorAttributeName, value: linkColor, range: result.rangeAt(0))
}
}
}
我在一个项目中使用了这个 NSMutableAttributedString extension
改编自这个 Article.
使用 NSRegularExpression
您可以指定与 link 文本范围相匹配的相应颜色:
分机:
extension NSMutableAttributedString {
func addLink(_ link: String, linkColor: UIColor, text: String) {
let pattern = "(\(text))"
let regex = try! NSRegularExpression(pattern: pattern,
options: NSRegularExpression.Options(rawValue: 0))
let matchResults = regex.matches(in: self.string,
options: NSRegularExpression.MatchingOptions(rawValue: 0),
range: NSRange(location: 0, length: self.string.characters.count))
for result in matchResults {
self.addAttribute(NSLinkAttributeName, value: link, range: result.rangeAt(0))
self.addAttribute(NSForegroundColorAttributeName, value: linkColor, range: result.rangeAt(0))
}
}
}
编辑:
设置自定义 UITextView class 以使用此扩展并使用委托函数 shouldInteractWith url 可以模拟 UITextView 的超级link 逻辑:
class CustomTextView: UITextView {
private let linksAttributes = [NSLinkAttributeName]
override func awakeFromNib() {
super.awakeFromNib()
let tapGest = UITapGestureRecognizer(target: self, action: #selector(self.onTapAction))
self.addGestureRecognizer(tapGest)
}
@objc private func onTapAction(_ tapGest: UITapGestureRecognizer) {
let location = tapGest.location(in: self)
let charIndex = self.layoutManager.characterIndex(for: location, in: self.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
if charIndex < self.textStorage.length {
var range = NSMakeRange(0, 0)
for linkAttribute in linksAttributes {
if let link = self.attributedText.attribute(linkAttribute, at: charIndex, effectiveRange: &range) as? String {
guard let url = URL(string: link) else { return }
_ = self.delegate?.textView?(self, shouldInteractWith: url, in: range, interaction: .invokeDefaultAction)
}
}
}
}
}
使用方法:
attributedString.addLink(yourLinkUrl, linkColor: yourLinkColor, text: yourLinkText)
let textView = CustomTextView()
textView.attributedText = attributedString