20

I have two NSStrings: orgText and searchLetter.
I want to highlight every occurrences of the searchLetter in the orgText with a red color.
How can I get the NSRange of all occurrences of the searchLetter ?
for eg :

suppose: orgText = "abcahaiapaoiuiapplma"
         searchLetter = "a".

I want to hightlight all "a" occurrences in "abcahaiapaoiuiapplma" with red color.
Thanks.

Arun_
  • 1,806
  • 2
  • 20
  • 40
Arun
  • 3,478
  • 8
  • 33
  • 46

4 Answers4

56

I wrote this method for my project - SUITextView with highlight:

- (NSMutableAttributedString*) setColor:(UIColor*)color word:(NSString*)word inText:(NSMutableAttributedString*)mutableAttributedString {

    NSUInteger count = 0, length = [mutableAttributedString length];
    NSRange range = NSMakeRange(0, length);

    while(range.location != NSNotFound)
    {
        range = [[mutableAttributedString string] rangeOfString:word options:0 range:range];
        if(range.location != NSNotFound) {
            [mutableAttributedString setTextColor:color range:NSMakeRange(range.location, [word length])];
            range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
            count++; 
        }
    }

    return mutableAttributedString;
}

And in my category of NSMutableAttributedString:

- (void) setTextColor:(UIColor*)color range:(NSRange)range {
    // kCTForegroundColorAttributeName
    [self removeAttribute:(NSString*)kCTForegroundColorAttributeName range:range]; // Work around for Apple leak
    [self addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)color.CGColor range:range];
}
Volodymyr B.
  • 3,369
  • 2
  • 30
  • 48
  • I think there's an extra "}" floating around, but working great still in '14 – dacopenhagen Aug 25 '14 at 23:46
  • @dacopenhagen you are right. that method was written for multiple words :) – Volodymyr B. Aug 26 '14 at 08:53
  • 1
    What's the point of count? To see how many occurrences you've replaced while debugging? – Ruiz Feb 19 '15 at 15:11
  • 1
    For me (iOS 7) it only worked with other kinds of arguments in that category method. `NSForegroundColorAttributeName` instead of `kCTForegroundColorAttributeName` and a `UIColor` object instead of its `CGColor` property. – anneblue Jul 15 '15 at 13:34
7

I'm not seeing any solution with regular expression, so I've created an elegant one, it may be useful for someone in the future.

- (BOOL)highlightString:(NSString *)string inText:(NSMutableAttributedString *)attributedString withColour:(UIColor *)color {
    NSError *_error;
    NSRegularExpression *_regexp = [NSRegularExpression regularExpressionWithPattern:string options:NSRegularExpressionCaseInsensitive error:&_error];
    if (_error == nil) {
        [_regexp enumerateMatchesInString:attributedString.string options:NSMatchingReportProgress range:NSMakeRange(0, attributedString.string.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
            if (result.numberOfRanges > 0) {
                for (int i = 0; i < result.numberOfRanges; i++) {
                    [attributedString addAttribute:NSBackgroundColorAttributeName value:color range:[result rangeAtIndex:i]];
                }
            }
        }];
        return TRUE;
    } else {
        return FALSE;
    }
}
holex
  • 23,961
  • 7
  • 62
  • 76
2

Code crash at "setTextColor" for MutableAttributeString

instead of it use below code

NSDictionary *tempdict=[NSDictionary dictionaryWithObjectsAndKeys:[UIFont boldSystemFontOfSize:12.0],NSFontAttributeName,color,NSForegroundColorAttributeName, nil];
[mutableAttributedString setAttributes:tempdict range:NSMakeRange(range.location, [word length])];
Fahim Parkar
  • 30,974
  • 45
  • 160
  • 276
-1

this is an easier way of doing it

NSString *str = @"hello world";
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:str];
[attr addAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} 
              range:[str rangeOfString:@"world"]];
abbood
  • 23,101
  • 16
  • 132
  • 246