2014-11-28 7 views
10

Dieser CodeFarbe alle Vorkommen der Zeichenkette in schnellen

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 

gibt NSRange mir eine Zeichenfolge innerhalb des Textview zu färben. Das Problem ist, dass ich nur das erste Vorkommen zurückgebe. Wenn das Wort "hi hihi hi" enthält, ist nur das erste "hi" farbig. Wie kann ich alle Vorkommen der Zeichenfolge erhalten?

+0

Ihre Lösung ist in Objective-C:/ – jjx

+0

Schrieb in Swift von http://stackoverflow.com/questions/8533691/how-to-get-all-nsrange-of-a-particular-character- in-a-nsstring? lq = 1 – Kevin

Antwort

21

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)) 
    } 
} 
3

Syntax Zucker für oben genannte Antwort Kevin.

wie Genannt:

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 
     } 
    } 
} 
+1

Zum Zwecke der Verbesserung meiner Antworten in der Zukunft können einige erklären, warum meine Antwort abgelehnt wurde? Die Verwendung einer Erweiterungsmethode scheint mir sauberer zu sein. – user1146169

+0

Danke! Ich fand das eine sehr nützliche und erweiterbare Möglichkeit für meinen Anwendungsfall. Vielleicht könnte ein Wörterbuch für mehrere Attribute verwendet werden? –

0

Mit NSRegularExpression erspart Ihnen auf alle selbst die Entfernungsberechnungen zu tun. In diesem Beispiel werden zwei Wörter statt nur einer hervorgehoben.

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) 
}