iosxcodensmutableattributedstringaddattribute

xcode iOS NSMutableAttributedString add attribute more than one time


I want to show the english date styled. I made the following code to get the characters to "redesign":

    - (NSMutableAttributedString *)attributedInfoString:(NSString *)string;
    {
        NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] initWithString:string];
        UIFont *smallFont = [UIFont boldSystemFontOfSize:17.0f];
        UIFont *boldFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:24.0f];

        [attString beginEditing];

        [attString addAttribute:NSFontAttributeName value:(smallFont) range:[string rangeOfString:@"th"]];
        [attString addAttribute:NSFontAttributeName value:(smallFont) range:[string rangeOfString:@"th" options:NSBackwardsSearch]];
        [attString addAttribute:(NSString*)kCTSuperscriptAttributeName value:@"1" range:[string rangeOfString:@"th"]];
        [attString addAttribute:(NSString*)kCTSuperscriptAttributeName value:@"1" range:[string rangeOfString:@"th" options:NSBackwardsSearch]];

        [attString addAttribute:NSFontAttributeName value:(boldFont) range:[string rangeOfString:@"the"]];
        [attString addAttribute:NSFontAttributeName value:(boldFont) range:[string rangeOfString:@"the" options:NSBackwardsSearch]];
        [attString addAttribute:(NSString*)kCTSuperscriptAttributeName value:@"0" range:[string rangeOfString:@"the"]];
        [attString addAttribute:(NSString*)kCTSuperscriptAttributeName value:@"0" range:[string rangeOfString:@"the" options:NSBackwardsSearch]];

        [attString addAttribute:NSFontAttributeName value:(smallFont) range:[string rangeOfString:@"st"]];
        [attString addAttribute:NSFontAttributeName value:(smallFont) range:[string rangeOfString:@"st" options:NSBackwardsSearch]];
        [attString addAttribute:(NSString*)kCTSuperscriptAttributeName value:@"1" range:[string rangeOfString:@"st"]];
        [attString addAttribute:(NSString*)kCTSuperscriptAttributeName value:@"1" range:[string rangeOfString:@"st" options:NSBackwardsSearch]];

        [attString addAttribute:NSFontAttributeName value:(boldFont) range:[string rangeOfString:@"August"]];
        [attString addAttribute:(NSString*)kCTSuperscriptAttributeName value:@"0" range:[string rangeOfString:@"August"]];

...

        [attString endEditing];
        return attString;
    }

The problem, I find only the first "hit" from the beginning or from the end. How can I arrange to search the whole string? Especially concerning the "th" because in the string is sometimes 5 or 6 times the word "the" which then stops the adding of the attributes.


Solution

  • I'm not sure of what you want to achieve. But this is what I usually use for adding attribute for a long string.

    - (NSMutableAttributedString *)attributedInfoString:(NSString *)string;
    {
        __block NSMutableAttributedString *attriString = [[NSMutableAttributedString alloc] initWithString:string];
    
        [attriString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15.0f] range:NSMakeRange(0, string.length)];
    
        UIFont *bold = [UIFont boldSystemFontOfSize:17.0f];
    
        __block BOOL mustStop = NO;
    
        [string enumerateSubstringsInRange:NSMakeRange(0, [string length])
                                   options:NSStringEnumerationByWords
                                usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop)
         {
             // terminates adding of attribute to string if YES
             // as you can see `og` from the word dog is ignored
             if (!mustStop)
             {
                 // since we are enumeratingByWord this is to check for specific string(word) in the `string`
                 // in this example `the` is the trigger to terminate adding attributes to mutableString
                 //
                 if (![substring isEqual:@"the"])
                 {
                     // add attribute if the substring(word) has `ox` or `og`
                     //
                     if ([substring rangeOfString:@"ox"].location != NSNotFound || [substring rangeOfString:@"og"].location != NSNotFound)
                     {
                         [attriString addAttribute:NSFontAttributeName value:bold range:substringRange];
                     }
    
                     else
                     {
                         // this is to add attribute to some specified `substring`
                         //
                         NSString *subsubString = @"uic";
    
                         NSRange subRange = [substring rangeOfString:subsubString];
    
                         if (subRange.location != NSNotFound)
                         {
                             substringRange.location += subRange.location;
    
                             substringRange.length = subsubString.length;
    
                             [attriString addAttribute:NSForegroundColorAttributeName value:[UIColor orangeColor] range:substringRange];
    
                             [attriString addAttribute:NSFontAttributeName value:bold range:substringRange];
                         }
                     }
                 } else mustStop = YES;
             }
         }
         ];
    
        return attriString;
    }
    

    If you use that like:

    title.attributedText = [self attributedInfoString:@"The quick brown fox jumped over the lazy dog"];
    

    sample output would be:

    enter image description here

    Hope this would help.. Cheers! :)