UITextView highlights all matches with swift

I want to highlight all matching words with the search. I wrote the code, but I could not use a loop. When I search for a word, my application finds words and selects only the first word. here is my code

var count = 0 let attributedText = NSMutableAttributedString(attributedString: txtMetin2.attributedText) let text2 = txtArama.text as NSString let text = txtMetin2.text as NSString var range:NSRange var checker:NSString = "" for(var i=0 ; i<text.length - text2.length-1 ; i++) { range = NSMakeRange(i, text2.length) checker = text.substringWithRange(range) if(text2 == checker) { count++ let highlightedRange = text.rangeOfString("\(text2)") attributedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.blueColor(), range: highlightedRange) let textAttachment = NSTextAttachment() let textAttachmentString = NSAttributedString(attachment: textAttachment) attributedText.appendAttributedString(textAttachmentString) txtMetin2.attributedText = attributedText } } println("\(count)") 

I am developing very fast. sorry for the bad coding. my codes find a match, but how can I highlight all the matches thanks

+9
source share
6 answers

Mandatory NSRegularExpression solution.

 let searchString = "this" let baseString = "This is some string that contains the word \"this\" more than once. This substring has multiple cases. ThisthisThIs." let attributed = NSMutableAttributedString(string: baseString) var error: NSError? let regex = NSRegularExpression(pattern: searchString, options: .CaseInsensitive, error: &error) if let regexError = error { println("Oh no! \(regexError)") } else { for match in regex?.matchesInString(baseString, options: NSMatchingOptions.allZeros, range: NSRange(location: 0, length: baseString.utf16Count)) as [NSTextCheckingResult] { attributed.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellowColor(), range: match.range) } textView.attributedText = attributed } 
+18
source

you can use the following function that passes the search input and current content. which will return an NSAttributedString? which you can set in TextView

Swift 3

 func generateAttributedString(with searchTerm: String, targetString: String) -> NSAttributedString? { let attributedString = NSMutableAttributedString(string: targetString) do { let regex = try NSRegularExpression(pattern: searchTerm, options: .caseInsensitive) let range = NSRange(location: 0, length: targetString.utf16.count) for match in regex.matches(in: targetString, options: .withTransparentBounds, range: range) { attributedString.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 16, weight: UIFontWeightBold), range: match.range) } return attributedString } catch _ { NSLog("Error creating regular expresion") return nil } } 

Edit:

highlight with diacritical insensitive option:

 func generateAttributedString(with searchTerm: String, targetString: String) -> NSAttributedString? { let attributedString = NSMutableAttributedString(string: targetString) do { let regex = try NSRegularExpression(pattern: searchTerm.trimmingCharacters(in: .whitespacesAndNewlines).folding(options: .diacriticInsensitive, locale: .current), options: .caseInsensitive) let range = NSRange(location: 0, length: targetString.utf16.count) for match in regex.matches(in: targetString.folding(options: .diacriticInsensitive, locale: .current), options: .withTransparentBounds, range: range) { attributedString.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 16, weight: UIFontWeightBold), range: match.range) } return attributedString } catch { NSLog("Error creating regular expresion: \(error)") return nil } } 
+5
source

Uitextview highlights all matches of the word swift 3.0

  let searchString = "Lorem Ipsum" let baseString = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry standard .Containing LOREM IPSUM passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem IPSUM" let attributed = NSMutableAttributedString(string: baseString) do { let regex = try! NSRegularExpression(pattern: searchString,options: .caseInsensitive) for match in regex.matches(in: baseString, options: NSRegularExpression.MatchingOptions(), range: NSRange(location: 0, length: baseString.characters.count)) as [NSTextCheckingResult] { attributed.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellow, range: match.range) } self.txtView.attributedText = attributed } 

click here to see image

+2
source

Enhanced Custom Solution for Swift 4.2

 extension NSAttributedString { convenience init(base: String, keyWords: [String], foregroundColor: UIColor, font: UIFont, highlightForeground: UIColor, highlighBackground: UIColor) { let baseAttributed = NSMutableAttributedString(string: base, attributes: [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: foregroundColor]) let range = NSRange(location: 0, length: base.utf16.count) for word in keyWords { guard let regex = try? NSRegularExpression(pattern: word, options: .caseInsensitive) else { continue } regex .matches(in: base, options: .withTransparentBounds, range: range) .forEach { baseAttributed .addAttributes([NSAttributedString.Key.backgroundColor: highlighBackground, NSAttributedString.Key.foregroundColor: highlightForeground], range: $0.range) } } self.init(attributedString: baseAttributed) } } 
+2
source

solvable.

this is new:

 var count = 0 let attributedText = NSMutableAttributedString(attributedString: txtMetin2.attributedText) let text2 = txtArama.text as NSString let text = txtMetin2.text as NSString println("\(text.length)") println("\(text2.length)") var range:NSRange var checker:NSString = "" for(var i=0 ; i <= text.length - text2.length ; i++) { range = NSMakeRange(i, text2.length) checker = text.substringWithRange(range) if(text2 == checker) { attributedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellowColor(), range: range) let textAttachment = NSTextAttachment() let textAttachmentString = NSAttributedString(attachment: textAttachment) attributedText.appendAttributedString(textAttachmentString) txtMetin2.attributedText = attributedText count++ } } println("\(count)") 

I used a range variable instead of the selected range in the Text.addAtrribute () attribute

0
source

Swift 4 and 5

 func generateAttributedString(with searchTerm: String, targetString: String) -> NSAttributedString? { let attributedString = NSMutableAttributedString(string: targetString) do { let regex = try NSRegularExpression(pattern: searchTerm.trimmingCharacters(in: .whitespacesAndNewlines).folding(options: .diacriticInsensitive, locale: .current), options: .caseInsensitive) let range = NSRange(location: 0, length: targetString.utf16.count) for match in regex.matches(in: targetString.folding(options: .diacriticInsensitive, locale: .current), options: .withTransparentBounds, range: range) { attributedString.addAttribute(NSAttributedString.Key.font, value: UIFont.systemFont(ofSize: 16, weight: UIFont.Weight.bold), range: match.range) } return attributedString } catch { NSLog("Error creating regular expresion: \(error)") return nil } } 
0
source

Source: https://habr.com/ru/post/1201220/


All Articles