Ios NSAttribute字符串中的彩色哈希标记
我有一个标签,其中有普通文本和hashtag。我希望标签有不同的颜色,所以我做了如下操作:Ios NSAttribute字符串中的彩色哈希标记,ios,nsattributedstring,Ios,Nsattributedstring,我有一个标签,其中有普通文本和hashtag。我希望标签有不同的颜色,所以我做了如下操作: let text = "#hellothere I am you. #hashtag #hashtag2 @you #hashtag3" let words = text.components(separatedBy: " ") let attribute = NSMutableAttributedString.init(string: text) for
let text = "#hellothere I am you. #hashtag #hashtag2 @you #hashtag3"
let words = text.components(separatedBy: " ")
let attribute = NSMutableAttributedString.init(string: text)
for word in words {
let range = (text as NSString).range(of: word)
if word.hasPrefix("#") {
attribute.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: range)
}
}
label.attributedText = attribute
然而,当我使用这种逻辑时,结果是不一致的。有时,hashtag会像预期的那样着色,有时包含hashtag的单词的某些部分会与下一个单词的某些部分一起着色。我正在寻找一种解决方案,我可以确定单词中是否有“#”字符(仅单词中的第一个出现),然后将单词从标签上标上颜色,直到下一个空格、逗号、分号、句号或字符串结尾,以适用的为准。我现在无法测试这一点,但我想到了一个想法; 当您在示例字符串中搜索字符串
#hashtag
时,您不认为它会找到三个位置,这可能与此有关吗?也许不是那个特定的示例字符串,但假设您有字符串“#hellother#hashtag2#hashtag#hashtag3”
,并执行代码。
当您循环到字符串“#hashtag”
并使用text.range(of:“#hashtag”)
时,它将首先找到字符串“#hashtag2”
。我不确定它是否会继续查找多个匹配项,但对于您的代码,“#hashtag2”
同样正确,因为它包含“#hashtag”
我不知道解决这个问题的最佳方法,但我有一些想法。
一个想法可能是以某种方式将字母存储在您要查找的单词之前和之后。因此,当您使用text.range(of:string)
时,您不仅要查找“#hashtag”
,还要查找“#hashtag”
。
仅仅在所讨论的字符串前后添加空格是不够的,因为它可能被另一个符号(逗号或句点等)分隔
更好的解决方案可能是汇总字符串的前面部分,并“手动”计算有问题字符串的范围,而不是使用text.range(of:string)
不是真正的代码,但试着理解我的想法:
let text = "#hellothere I am you. #hashtag #hashtag2 @you #hashtag3"
let words = text.components(separatedBy: " ")
let attribute = NSMutableAttributedString.init(string: text)
for (index, word) in words.enumerated() {
if word.hasPrefix("#") {
//Recreate the original string up to this part, so you can find the actual start-index of your current word.
let sentenceBeforeWord = words[0..<index].joined(separator: " ")
let range = //
attribute.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: range)
}
}
label.attributedText = attribute
let text=“#你好,我是你。#hashtag#hashtag2@you#hashtag3”
让words=text.components(以:“”分隔)
let attribute=NSMutableAttributedString.init(字符串:文本)
用于(索引,单词)的文字。枚举(){
if word.hasPrefix(“#”){
//重新创建此部分之前的原始字符串,以便可以找到当前单词的实际起始索引。
让sentenceBeforeWord=words[0..这需要一个正则表达式
let attrStr = NSMutableAttributedString(string: "#hellothere I am you. #hashtag, #hashtag2 @you #hashtag3")
let searchPattern = "#\\w+"
var ranges: [NSRange] = [NSRange]()
let regex = try! NSRegularExpression(pattern: searchPattern, options: [])
ranges = regex.matches(in: attrStr.string, options: [], range: NSMakeRange(0, attrStr.string.characters.count)).map {$0.range}
for range in ranges {
attrStr.addAttribute(NSForegroundColorAttributeName, value: UIColor.yellow, range: NSRange(location: range.location, length: range.length))
}
attrStr
将上面的内容粘贴到游戏中并查看输出。若要查看正则表达式的运行情况,请尝试此操作。您的代码似乎工作正常,您能否提供一个不起作用的示例
不过,您可以做一些小的改进:
let text: NSString = "#hellothere I am you. #hashtag #hashtag2 @you #hashtag3"
let words = text.components(separatedBy: " ").filter { $0.hasPrefix("#") }
let attributed = NSMutableAttributedString(string: text as String)
for word in words {
attributed.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: text.range(of: word))
}
无需调用NSMutableAttributedString.init(string:text)
具体来说,您可以使用NSMutableAttributedString(string:text)
您可以在数组上使用filter将其直接缩减为hashtag值,而无需在for循环期间检查hashtag
我建议将该字符串声明为NSString,这样您就不需要在每次迭代过程中强制转换它-但是,您需要为NSMutableAttributedString初始化强制转换它
@schmubob的正则表达式解决方案对我来说很好。不过,我也会尝试一下:)