6

I am trying to make multiple occurrences in a attributed string bold using something like the following

[attrStr setFont:[UIFont ...] range:[attrStr.string rangeOfString:@"hello world"]]; 

As you know, 'rangeOfString' always return the FIRST occurrence of the match... I am still quite new to iOS, just wondering what's the best way to set all occurrences to bold... Is there any function provided in NSString or something?

Thanks in advance!

1
  • No response from the original poster as to the outcome. Commented Apr 17, 2013 at 13:58

3 Answers 3

24

You should first try to get all ranges in the string and then set the attribute for every range. There are some great code examples right here on stackoverflow: https://stackoverflow.com/a/4653266/381870

Edit:

Here's an example for you

- (NSArray *)rangesOfString:(NSString *)searchString inString:(NSString *)str { NSMutableArray *results = [NSMutableArray array]; NSRange searchRange = NSMakeRange(0, [str length]); NSRange range; while ((range = [str rangeOfString:searchString options:0 range:searchRange]).location != NSNotFound) { [results addObject:[NSValue valueWithRange:range]]; searchRange = NSMakeRange(NSMaxRange(range), [str length] - NSMaxRange(range)); } return results; } 

Usage:

NSArray *results = [self rangesOfString:@"foo" inString:@"foo bar foo"]; NSLog(@"%@", results); 

gives you

( "NSRange: {0, 3}", "NSRange: {8, 3}" ) 
Sign up to request clarification or add additional context in comments.

1 Comment

brilliant answer..save my day
1

Converting Tim's answer to Swift 4:

extension NSString { open func ranges(of searchString: String) -> [NSRange] { var ranges = [NSRange]() var searchRange = NSRange(location: 0, length: self.length) var range: NSRange = self.range(of: searchString) while range.location != NSNotFound { ranges.append(range) searchRange = NSRange(location: NSMaxRange(range), length: self.length - NSMaxRange(range)) range = self.range(of: searchString, options: [], range: searchRange) } return ranges } } 

Also did it to Swift's String primitive:

extension String { func ranges(of substring: String, options: CompareOptions = [], locale: Locale? = nil) -> [Range<Index>] { var ranges: [Range<Index>] = [] while let range = self.range(of: substring, options: options, range: (ranges.last?.upperBound ?? self.startIndex)..<self.endIndex, locale: locale) { ranges.append(range) } return ranges } } 

Comments

0

You will like have to use NSScanner to scan through the text and replace it.You can find an example for NSScanner here.

1 Comment

Thanks @Vignesh for the info. I will take a look at this option... I chose the above solution because it's kinda more consistent with my current codebase. :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.