获取属性字符串的颜色变化词

Get color changed words of attributed string

我有一个 UITextView 允许 select 通过点击文本中的单词。如果点击它,则通过更改 NSForegroundColor 属性,单词会以颜色突出显示。 再次点击它,通过将颜色改回文本颜色来取消select它。

现在我需要知道 UITextView.

中的所有 selected 单词

第一个想法是删除所有特殊字符并在 space 处拆分文本。然后检查颜色属性是否等于每个单独单词的 selected/highlighted 颜色。 但是属性字符串不允许在字符处拆分或删除组件。 NSAttributedString.

也没有

第二个想法是将突出显示部分的范围保存在一个数组中并对其进行迭代以获取突出显示的部分。但这对我来说似乎有点太复杂了,尤其是当我需要单词出现时的正确顺序时,数组不能保证,每次点击 add/remove (例如,假设文本是:"This is a test"

Tap this -> index 0
Tap test -> index 1
Tap this -> test becomes index 0
Tap this -> this becomes index 1

那么顺序就不行了

我已经想出了如何获取属性字符串的颜色。那不是问题。

如何遍历属性字符串并找出颜色改变的单词或解决此问题的最佳方法是什么?

谢谢!

问候

我可以建议你为选定的范围创建某种存储,然后基于这个范围你可以自定义这个词的外观,而不是其他方式。它将允许您每次访问选定的单词而无需检查整个文本的属性。

虽然我同意 Piotr 你应该存储 Ranges,但回答你的问题:

attributedString.enumerateAttributes(in: NSMakeRange(0, attributedString.length), options: []) { attributes, range, _ in
    if let color = attributes[NSForegroundColorAttributeName] as? UIColor,
        color == YOUR_HIGHLIGHT_COLOR {
        let nString = attributedString.string as NSString
        let word = nString.substring(with: range)
        // Do what you want with the word
    }
}

您可以遍历属性字符串以查找颜色属性。

下面的代码演示了如何:

// This generates a test attributed string.
// You actually want the attributedText property of your text view
let str = NSMutableAttributedString(string: "This is a test of the following code")
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(0, 4))
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(8, 1))
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(15, 2))
print(str)

以上打印:

This{
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1";
} is {
}a{
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1";
} test {
}of{
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1";
} the following code{
}

此代码处理属性字符串。任何范围的前景色格式的文本都将放入 words 数组中。

var words = [String]()
str.enumerateAttribute(NSForegroundColorAttributeName, in: NSMakeRange(0, str.length), options: []) { (value, range, stop) in
    if value != nil {
        let word = str.attributedSubstring(from: range).string
        words.append(word)
    }
}
print(words)

这会打印:

["This", "a", "of"]