String
ช่วงและช่วงSwift 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)
เอาท์พุท:
par ยาว paragra {
} ph say {
NSColor = "NSCalibratedRGBColorSpace 1 0 0 1";
ไอเอ็นจี}! {
}
ตามที่คุณเห็น "ph say" ถูกทำเครื่องหมายด้วยแอตทริบิวต์ไม่ใช่ "กำลังพูด"
เนื่องจาก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)
เอาท์พุท:
😄😄😄วรรคยาว {
} {พูด
NSColor = "NSCalibratedRGBColorSpace 1 0 0 1";
}! {
}
อัปเดตสำหรับ 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)
อัปเดตสำหรับ 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)
อัปเดตสำหรับ Swift 4:
ในฐานะของสวิฟท์ 4 (Xcode 9), ห้องสมุดมาตรฐานสวิฟท์มีวิธีการแปลงระหว่างและRange<String.Index>
NSRange
แปลงไปNSString
เป็นไม่จำเป็นอีกต่อไป:
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
คือ a Range<String.Index>
และนั่นถูกแปลงให้สอดคล้องNSRange
กับ
NSRange(substringRange, in: text)