在swift中对所有出现的string进行着色

这个代码

var textSearch="hi" var textToShow="hi hihi hi" var rangeToColor = (textToShow as NSString).rangeOfString(textSearch) var attributedString = NSMutableAttributedString(string:textToShow) attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.yellowColor() , range: rangeToColor) TextView.attributedText=attributedString 

给我NSRange在TextView中为string着色。 问题是我只返回第一次出现。 如果单词包含“hi hihi hi”,则只有第一个“hi”被着色。 我怎样才能得到所有的string?

Swift 3

 let attrStr = NSMutableAttributedString(string: "hi hihi hey") let inputLength = attrStr.string.characters.count let searchString = "hi" let searchLength = searchString.characters.count var range = NSRange(location: 0, length: attrStr.length) while (range.location != NSNotFound) { range = (attrStr.string as NSString).range(of: searchString, options: [], range: range) if (range.location != NSNotFound) { attrStr.addAttribute(NSForegroundColorAttributeName, value: UIColor.yellow(), range: NSRange(location: range.location, length: searchLength)) range = NSRange(location: range.location + range.length, length: inputLength - (range.location + range.length)) } } 

Swift 2

 let attrStr = NSMutableAttributedString(string: "hi hihi hey") let inputLength = attrStr.string.characters.count let searchString = "hi" let searchLength = searchString.characters.count var range = NSRange(location: 0, length: attrStr.length) while (range.location != NSNotFound) { range = (attrStr.string as NSString).rangeOfString(searchString, options: [], range: range) if (range.location != NSNotFound) { attrStr.addAttribute(NSForegroundColorAttributeName, value: UIColor.yellowColor(), range: NSRange(location: range.location, length: searchLength)) range = NSRange(location: range.location + range.length, length: inputLength - (range.location + range.length)) } } 

上面的凯文答案的语法糖。

被调用如:

 attrStr.attributeRangeFor(searchString, attributeValue: UIColor.yellowColor(), atributeSearchType: .All) 

Swift 2.0:

 import UIKit extension NSMutableAttributedString { enum AtributeSearchType { case First, All, Last } func attributeRangeFor(searchString: String, attributeValue: AnyObject, atributeSearchType: AtributeSearchType) { let inputLength = self.string.characters.count let searchLength = searchString.characters.count var range = NSRange(location: 0, length: self.length) var rangeCollection = [NSRange]() while (range.location != NSNotFound) { range = (self.string as NSString).rangeOfString(searchString, options: [], range: range) if (range.location != NSNotFound) { switch atributeSearchType { case .First: self.addAttribute(NSForegroundColorAttributeName, value: attributeValue, range: NSRange(location: range.location, length: searchLength)) return case .All: self.addAttribute(NSForegroundColorAttributeName, value: attributeValue, range: NSRange(location: range.location, length: searchLength)) break case .Last: rangeCollection.append(range) break } range = NSRange(location: range.location + range.length, length: inputLength - (range.location + range.length)) } } switch atributeSearchType { case .Last: let indexOfLast = rangeCollection.count - 1 self.addAttribute(NSForegroundColorAttributeName, value: attributeValue, range: rangeCollection[indexOfLast]) break default: break } } } 

使用NSRegularExpression你自己做所有的范围计算。 这个例子也会突出显示两个单词而不是一个单词。

 let text = "If you don't have a plan, you become part of somebody else's plan." let toHighlight = ["plan", "you"] let range = text.nsRange(from: text.startIndex ..< text.endIndex) // full text let rangesToHighlight: [[NSRange]] = toHighlight.map { search in do { let regex = try NSRegularExpression(pattern: search, options: []) let matches: [NSTextCheckingResult] = regex.matches(in: text, options: [], range: range) return matches.map { $0.range } // get range from NSTextCheckingResult } catch { return [NSRange]() } } let yellow = UIColor.yellow let attributedText = NSMutableAttributedString(string: text) let flattenedRanges: [NSRange] = rangesToHighlight.joined() flattenedRanges.forEach { // apply color to all ranges attributedText.addAttribute(NSForegroundColorAttributeName, value: yellow, range: $0) }