Monday, February 22, 2016

Objective C Attributed Strings

We can only apply one font style and color to a static text using strings while displaying in UILabel. What if we need to highlight some thing in the static text we want to display. Like a folder has been renamed in the server and we need to notify the user about this change.

Using NSString we can display in a single color like shown below.



  
myLabel.text = @"folder_old has been renamed to folder_new.";


folder_old has been renamed to folder_new.   

In this case, We need to highlight both old name and new names of the folder as shown below.

folder_old has been renamed to folder_new.


We can do this using the NSAttributed string.


                         



Here is the Objective C code do this.



 - (NSAttributedString *)getAttributedStringWithOldItemName:(NSString *)oldName andNewName:    
                                                                                                                     (NSString *)newName
 {
    
    NSString *staticText = @" has been renamed to ";
    
    NSString *fullText = [[oldName stringByAppendingString:staticText] 
                                                               stringByAppendingString:newName];

    
    // Define general attributes for the entire text
    NSDictionary *attribs = [[NSDictionary alloc] initWithObjectsAndKeys:[UIColor 
            blackColor],NSForegroundColorAttributeName,
            [UIFont fontWithName:@"ArialMT" size:16],NSFontAttributeName, nil];
                                                                               
    
    NSMutableAttributedString *attributedText =
                    [[NSMutableAttributedString alloc] initWithString:fullText
                                                                                 attributes:attribs];
    
    // Old Name text attributes
    NSRange oldNameTextRange = NSMakeRange(0, oldName.length);
    
    [attributedText setAttributes:[[NSDictionary alloc] initWithObjectsAndKeys:
             [UIColor redColor],NSForegroundColorAttributeName,             
             [UIFont fontWithName:@"ArialMT" size:16],NSFontAttributeName, nil]
                                                                             range:oldNameTextRange];
                                                                                          
    
    
    // has been renamed to attributes
    NSRange staticTextRange = [fullText rangeOfString:staticText];
    
    [attributedText setAttributes: [[NSDictionary alloc] initWithObjectsAndKeys: 
                             [UIColor darkGrayColor],NSForegroundColorAttributeName, 
                             [UIFont fontWithName:@"ArialMT" size:16],
                             NSFontAttributeName, nil] range:staticTextRange];
                                                                                                
    
    //New Name text attributes
    NSRange newNameRange = [fullText rangeOfString:newName];
    
    [attributedText setAttributes: [[NSDictionary alloc] initWithObjectsAndKeys:                
                                        [UIColor blueColor],NSForegroundColorAttributeName,                
                                        [UIFont fontWithName:@"ArialMT" size:16],NSFontAttributeName, nil]
                                        range:newNameRange];                                                                                                                          
    
    return attributedText;

 } 



NSAttributedString is having attributes param, using which we can customize text color and font of a sub string in our full string as shown in the above code. We can range of our substring and assign our required color and font.

I have applied blue color to my folder old name and red color to my folder new name. In that way I am highlighting my required substrings in a string.

Now I can assign it o my label using the attributedText parameter of the UILabel as shown below.



  
self.attLabel.attributedText = 
                [self getAttributedStringWithOldItemName:@"folder_old" andNewName:@"folder_new"];


There are different attributes which we can customize. We can strike a text, we can apply background color, we can apply underline etc...

Here are different attributes available as per the Apple documentation(NSAttributedString.h).



 NSFontAttributeName NS_AVAILABLE_IOS(6_0);
 NSParagraphStyleAttributeName NS_AVAILABLE_IOS(6_0); 
 NSForegroundColorAttributeName NS_AVAILABLE_IOS(6_0); 
 NSBackgroundColorAttributeName NS_AVAILABLE_IOS(6_0);
 NSLigatureAttributeName NS_AVAILABLE_IOS(6_0); 
 NSKernAttributeName NS_AVAILABLE_IOS(6_0);   
 NSStrikethroughStyleAttributeName NS_AVAILABLE_IOS(6_0); 
 NSUnderlineStyleAttributeName NS_AVAILABLE_IOS(6_0); 
 NSStrokeColorAttributeName NS_AVAILABLE_IOS(6_0); 
 NSStrokeWidthAttributeName NS_AVAILABLE_IOS(6_0); 
 NSShadowAttributeName NS_AVAILABLE_IOS(6_0);
 NSTextEffectAttributeName NS_AVAILABLE_IOS(7_0);
 NSAttachmentAttributeName NS_AVAILABLE_IOS(7_0); 
 NSLinkAttributeName NS_AVAILABLE_IOS(7_0);
 NSBaselineOffsetAttributeName NS_AVAILABLE_IOS(7_0); 
 NSUnderlineColorAttributeName NS_AVAILABLE_IOS(7_0); 
 NSStrikethroughColorAttributeName NS_AVAILABLE_IOS(7_0);  
 NSObliquenessAttributeName NS_AVAILABLE_IOS(7_0);  
 NSExpansionAttributeName NS_AVAILABLE_IOS(7_0);  
 NSWritingDirectionAttributeName NS_AVAILABLE_IOS(7_0);   
 NSVerticalGlyphFormAttributeName NS_AVAILABLE_IOS(6_0);   


Hope this post is useful. Feel free to comment in case of any queries.