如何更改标签中每 5 个第一个单词的文本颜色?
How I can change text color for every 5 first words in label?
我从 API 得到了不同的文本,我想为每 5 个第一个单词更改文本颜色。我尝试使用范围和属性字符串,但我做错了,这对我来说不是很好。我该怎么做?
这是我的代码:
private func setMessageText(text: String) {
let components = text.components(separatedBy: .whitespacesAndNewlines)
let words = components.filter { ![=10=].isEmpty }
if words.count >= 5 {
let attribute = NSMutableAttributedString.init(string: text)
var index = 0
for word in words where index < 5 {
let range = (text as NSString).range(of: word, options: .caseInsensitive)
attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: Colors.TitleColor, range: range)
attribute.addAttribute(NSAttributedString.Key.font, value: Fonts.robotoBold14, range: range)
index += 1
}
label.attributedText = attribute
} else {
label.text = text
}
}
enter image description here
获取第5个单词末尾的索引并为整个范围添加一次颜色和字体会更有效。
并且强烈建议您不要将 String
桥接到 NSString
以从字符串中获取子范围。 不要那样做。使用原生 Swift Range<String.Index>
,有一个方便的 API 可以可靠地将 Range<String.Index>
转换为 NSRange
。
private func setMessageText(text: String) {
let components = text.components(separatedBy: .whitespacesAndNewlines)
let words = components.filter { ![=10=].isEmpty }
if words.count >= 5 {
let endOf5thWordIndex = text.range(of: words[4])!.upperBound
let nsRange = NSRange(text.startIndex..<endOf5thWordIndex, in: text)
let attributedString = NSMutableAttributedString(string: text)
attributedString.addAttributes([.foregroundColor : Colors.TitleColor, .font : Fonts.robotoBold14], range: nsRange)
label.attributedText = attributedString
} else {
label.text = text
}
}
另一种更复杂的方法是使用带有选项 byWords
的专用 API enumerateSubstrings(in:options:
func setMessageText(text: String) {
var wordIndex = 0
var attributedString : NSMutableAttributedString?
text.enumerateSubstrings(in: text.startIndex..., options: .byWords) { (substring, substringRange, enclosingRange, stop) in
if wordIndex == 4 {
let endIndex = substringRange.upperBound
let nsRange = NSRange(text.startIndex..<endIndex, in: text)
attributedString = NSMutableAttributedString(string: text)
attributedString!.addAttributes([.foregroundColor : Colors.TitleColor, .font : Fonts.robotoBold14], range: nsRange)
stop = true
}
wordIndex += 1
}
if let attributedText = attributedString {
label.attributedText = attributedText
} else {
label.text = text
}
}
我从 API 得到了不同的文本,我想为每 5 个第一个单词更改文本颜色。我尝试使用范围和属性字符串,但我做错了,这对我来说不是很好。我该怎么做?
这是我的代码:
private func setMessageText(text: String) {
let components = text.components(separatedBy: .whitespacesAndNewlines)
let words = components.filter { ![=10=].isEmpty }
if words.count >= 5 {
let attribute = NSMutableAttributedString.init(string: text)
var index = 0
for word in words where index < 5 {
let range = (text as NSString).range(of: word, options: .caseInsensitive)
attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: Colors.TitleColor, range: range)
attribute.addAttribute(NSAttributedString.Key.font, value: Fonts.robotoBold14, range: range)
index += 1
}
label.attributedText = attribute
} else {
label.text = text
}
}
enter image description here
获取第5个单词末尾的索引并为整个范围添加一次颜色和字体会更有效。
并且强烈建议您不要将 String
桥接到 NSString
以从字符串中获取子范围。 不要那样做。使用原生 Swift Range<String.Index>
,有一个方便的 API 可以可靠地将 Range<String.Index>
转换为 NSRange
。
private func setMessageText(text: String) {
let components = text.components(separatedBy: .whitespacesAndNewlines)
let words = components.filter { ![=10=].isEmpty }
if words.count >= 5 {
let endOf5thWordIndex = text.range(of: words[4])!.upperBound
let nsRange = NSRange(text.startIndex..<endOf5thWordIndex, in: text)
let attributedString = NSMutableAttributedString(string: text)
attributedString.addAttributes([.foregroundColor : Colors.TitleColor, .font : Fonts.robotoBold14], range: nsRange)
label.attributedText = attributedString
} else {
label.text = text
}
}
另一种更复杂的方法是使用带有选项 byWords
enumerateSubstrings(in:options:
func setMessageText(text: String) {
var wordIndex = 0
var attributedString : NSMutableAttributedString?
text.enumerateSubstrings(in: text.startIndex..., options: .byWords) { (substring, substringRange, enclosingRange, stop) in
if wordIndex == 4 {
let endIndex = substringRange.upperBound
let nsRange = NSRange(text.startIndex..<endIndex, in: text)
attributedString = NSMutableAttributedString(string: text)
attributedString!.addAttributes([.foregroundColor : Colors.TitleColor, .font : Fonts.robotoBold14], range: nsRange)
stop = true
}
wordIndex += 1
}
if let attributedText = attributedString {
label.attributedText = attributedText
} else {
label.text = text
}
}