SWIFT String
范围和NSString
范围不"兼容".
例如,像?这样的表情符号被算作一个Swift 字符,但却被算作两个NSString
字符(所谓的UTF-16代理项对).
因此,如果字符串中包含您建议的解决方案,则会产生意想不到的结果
包含这样的字符.示例:
let text = "???Long paragraph saying!"
let textRange = text.startIndex..<text.endIndex
let attributedString = NSMutableAttributedString(string: text)
text.enumerateSubstringsInRange(textRange, options: NSStringEnumerationOptions.ByWords, { (substring, substringRange, enclosingRange, stop) -> () in
let start = distance(text.startIndex, substringRange.startIndex)
let length = distance(substringRange.startIndex, substringRange.endIndex)
let range = NSMakeRange(start, length)
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.redColor(), range: range)
}
})
println(attributedString)
输出:
???Long paragra{
}ph say{
NSColor = "NSCalibratedRGBColorSpace 1 0 0 1";
}ing!{
}
如您所见,"ph say"已标记为属性,而不是"saying".
因为NS(Mutable)AttributedString
最终需要NSString
和NSRange
,所以它实际上是
最好先将给定的字符串转换为NSString
.然后是substringRange
路
是NSRange
,您不再需要转换范围:
let text = "???Long paragraph saying!"
let nsText = text as NSString
let textRange = NSMakeRange(0, nsText.length)
let attributedString = NSMutableAttributedString(string: nsText)
nsText.enumerateSubstringsInRange(textRange, options: NSStringEnumerationOptions.ByWords, { (substring, substringRange, enclosingRange, stop) -> () in
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.redColor(), range: substringRange)
}
})
println(attributedString)
输出:
???Long paragraph {
}saying{
NSColor = "NSCalibratedRGBColorSpace 1 0 0 1";
}!{
}
Update for Swift 2:个
let text = "???Long paragraph saying!"
let nsText = text as NSString
let textRange = NSMakeRange(0, nsText.length)
let attributedString = NSMutableAttributedString(string: text)
nsText.enumerateSubstringsInRange(textRange, options: .ByWords, usingBlock: {
(substring, substringRange, _, _) in
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.redColor(), range: substringRange)
}
})
print(attributedString)
Update for Swift 3:个
let text = "???Long paragraph saying!"
let nsText = text as NSString
let textRange = NSMakeRange(0, nsText.length)
let attributedString = NSMutableAttributedString(string: text)
nsText.enumerateSubstrings(in: textRange, options: .byWords, using: {
(substring, substringRange, _, _) in
if (substring == "saying") {
attributedString.addAttribute(NSForegroundColorAttributeName, value: NSColor.red, range: substringRange)
}
})
print(attributedString)
Update for Swift 4:
从Swift 4(Xcode 9)开始,Swift标准库
let text = "???Long paragraph saying!"
let attributedString = NSMutableAttributedString(string: text)
text.enumerateSubstrings(in: text.startIndex..<text.endIndex, options: .byWords) {
(substring, substringRange, _, _) in
if substring == "saying" {
attributedString.addAttribute(.foregroundColor, value: NSColor.red,
range: NSRange(substringRange, in: text))
}
}
print(attributedString)
这里substringRange
是Range<String.Index>
,它被转换成
NSRange(substringRange, in: text)