Particular characters are to be highlighted in red color on the label so I wrote below function which works well, but I want to confirm, is there any other efficient way of doing this ? e.g.
-(NSMutableAttributedString*)getAttributeText:(NSString*)string forSubstring:(NSString*)searchstring {
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:_lblName.text];
NSRange searchRange = NSMakeRange(0,string.length);
for (NSInteger charIdx=0; charIdx<searchstring.length; charIdx++){
NSString *substring = [searchstring substringWithRange:NSMakeRange(charIdx, 1)];
NSRange foundRange;
searchRange.location = 0;
while (searchRange.location < string.length) {
searchRange.length = string.length-searchRange.location;
foundRange = [string rangeOfString:substring options:1 range:searchRange];
[text addAttribute: NSForegroundColorAttributeName value: [UIColor redColor] range:foundRange];
if (foundRange.location != NSNotFound) {
searchRange.location = foundRange.location+foundRange.length;
} else {
// no more substring to find
break;
}
}
}
return text;
}
Below is the code how I use it, and result as well
NSString *string = @"James Bond Always Rocks";
_lblName.text = string;
_lblAttributedName.attributedText = [self getAttributeText:string forSubstring:@"ao"];
Update
NSString *string = @"James Bond Always Rocks";
NSRange range = [string rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"J"] options:NSCaseInsensitiveSearch];
NSLog(@"range->%@",NSStringFromRange(range)); //This prints range->{0, 1}
NSString *string = @"James Bond Always Rocks";
NSRange range = [string rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"j"] options:NSCaseInsensitiveSearch];
NSLog(@"range->%@",NSStringFromRange(range)); //This prints range->{2147483647, 0}
You can simplify it by searching for a pattern ("[ao]+" in your example) to eliminate the outer loop:
NSString *string = @"James Bond Always Rocks";
NSString *searchstring = @"ao";
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:string];
// A regular expression pattern that matches a sequence of the characters in "searchString":
NSString *pattern = [NSString stringWithFormat:@"[%@]+", [NSRegularExpression escapedPatternForString:searchstring]];
NSRange foundRange = [string rangeOfString:pattern options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];
while (foundRange.location != NSNotFound) {
[text addAttribute: NSForegroundColorAttributeName value: [UIColor redColor] range:foundRange];
NSRange nextRange = NSMakeRange(foundRange.location + foundRange.length, string.length - foundRange.location - foundRange.length);
foundRange = [string rangeOfString:pattern options:NSRegularExpressionSearch|NSCaseInsensitiveSearch range:nextRange];
}
Here is my version, this is very basic approach using simple loops.
Why I posted it because I tracked the efficiency and please see the time taken by each of the implementations.
2014-03-14 15:48:42.792 TimeEfficiency[1166:303] My: 0.000073 seconds
2014-03-14 15:48:45.319 TimeEfficiency[1166:303] martin: 0.000278 seconds
2014-03-14 15:48:48.263 TimeEfficiency[1166:303] avt: 0.000029 seconds
2014-03-14 15:48:51.152 TimeEfficiency[1166:303] janak: 0.000092 seconds
Hence Avt's is best in time-performance.
NSString *string = @"James Bond Always Rocks";
NSString *searchstring = @"ao";
NSMutableArray *characters = [NSMutableArray new];
for (NSInteger i=0; i<searchstring.length; i++) {
[characters addObject:[searchstring substringWithRange:NSMakeRange(i, 1)]]; //ao
}
//store all the location of each of the char
NSMutableArray *locations = [NSMutableArray new];
for (NSInteger i=0; i<string.length; i++) {
if ([characters containsObject: [string substringWithRange:NSMakeRange(i, 1)]] ){
[locations addObject:@(i)];
}
}
//loop for string and for each location change the color
NSMutableAttributedString *text = [[NSMutableAttributedString alloc]initWithString:string];
for (NSInteger i=0; i<locations.count; i++) {
NSRange range=NSMakeRange([locations[i] intValue], 1);
[text addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:range];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With