Showing posts with label NSFontAttributeName. Show all posts
Showing posts with label NSFontAttributeName. Show all posts

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.

Tuesday, February 9, 2016

Objective C UITableViewCell height based on content

Usually we set a height for table view cell in the heightForRowAtIndexPath delegate method. If our content text is more on the textLabel, we go for the middle or tail truncation of the text. When user clicks on the cell we open a view and display the full content generally.

What If you got a requirement like, we have to show all the content without any truncations in the cell. In this case the challenge is, cell height should be dynamic based on the content length. In this post let's see how we can achieve this functionality.


                         



From iOS 7.0 we have boundingRectWithSize string method, which gives us the frame required for a string based on the below factors.


  • Maximum width of the label in which we are going to display our text.
  • The label font type and size that we are using.



  
  NSString *message = @"-----LONG CONTENT HERE-----";

  CGSize maximumLabelSize = CGSizeMake(IS_IPA?300-80:180-80, CGFLOAT_MAX);
    
  CGRect textRect = [message boundingRectWithSize:maximumLabelSize

                                             options:NSStringDrawingUsesLineFragmentOrigin| 
                                                         NSStringDrawingUsesFontLeading

                                             attributes:@{NSFontAttributeName:
                                             [UIFont fontWithName:@"Verdana" size:14]} context:nil];                                                                                     


    
Use the above logic in your heightForRowAtIndexPath delegate method and take height from the frame that is given by the boundingRectWithSize method.


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