Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easiest way to style the text of an UILabel in iOS7/iOS8

I'm learning objective c a little bit to write an iPad app. I've mostly done some html5/php projects and learned some python at university. But one thing that really blows my mind is how hard it is to just style some text in an objective C label.

Maybe I'm coming from a lazy markdown generation, but really, if I want to let an UILabel look like:

Objective: Construct an equilateral triangle from the line segment AB.

In markdown this is as simple as:

**Objective:** Construct an *equilateral* triangle from the line segment AB.

Is there really no pain free objective C way to do this ? All the tutorials I read really wanted me to write like 15 lines of code. For something as simple as this.

So my question is, what is the easiest way to do this, if you have a lot of styling to do in your app ? Will styling text become more natural with swift in iOS8 ?

like image 401
90intuition Avatar asked Oct 30 '25 01:10

90intuition


2 Answers

You can use NSAttributedString's data:options:documentAttributes:error: initializer (first available in iOS 7.0 SDK).

import UIKit

let htmlString = "<b>Objective</b>: Construct an <i>equilateral</i> triangle from the line segment AB."
let htmlData = htmlString.dataUsingEncoding(NSUTF8StringEncoding)

let options = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType]
var error : NSError? = nil

let attributedString = NSAttributedString(data: htmlData, options: options, documentAttributes: nil, error: &error)

if error == nil {
    // we're good
}

Note: You might also want to include NSDefaultAttributesDocumentAttribute option in the options dictionary to provide additional global styling (such as telling not to use Times New Roman).

Take a look into NSAttributedString UIKit Additions Reference for more information.

like image 126
akashivskyy Avatar answered Nov 01 '25 17:11

akashivskyy


I faced similar frustrations while trying to use attributed text in Xcode, so I feel your pain. You can definitely use multiple NSMutableAttributedtext's to get the job done, but this is very rigid.

UIFont *normalFont = [UIFont fontWithName:@"..." size:20];
UIFont *boldFont = [UIFont fontWithName:@"..." size:20];
UIFont *italicizedFont = [UIFont fontWithName:@"..." size:20];
NSMutableAttributedString *total = [[NSMutableAttributedString alloc]init];

NSAttributedString *string1 = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"Objective"] attributes:@{NSFontAttributeName:boldFont}];

NSAttributedString *string2 = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@": Construct an "] attributes:@{NSFontAttributeName:normalFont}];

NSAttributedString *string3 = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"equilateral "] attributes:@{NSFontAttributeName:italicizedFont}];

NSAttributedString *string4 = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"triangle from the line segment AB."] attributes:@{NSFontAttributeName:normalFont}];

[total appendAttributedString:string1];
[total appendAttributedString:string2];
[total appendAttributedString:string3];
[total appendAttributedString:string4];

[self.someLabel setAttributedText: total];

Another option is to use NSRegularExpression. While this will require more lines of code, it is a more fluid way of bolding, changing color, etc from an entire string at once. For your purposes however, using the appendAttributedString will be the shortest way with a label.

    UIFont *normalFont = [UIFont fontWithName:@"..." size:20];
    UIFont *boldFont = [UIFont fontWithFamilyName:@"..." size: 20];
    UIFont *italicizedFont = [UIFont fontWithFamilyName:@"..." size: 20];

    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat: @"Objective: Construct an equilateral triangle from the line segment AB."] attributes:@{NSFontAttributeName:normalFont}];

    NSError *regexError;

    NSRegularExpression *regex1 = [NSRegularExpression regularExpressionWithPattern:@"Objective"
                                                                              options:NSRegularExpressionCaseInsensitive error:&regexError];
    NSRegularExpression *regex2 = [NSRegularExpression regularExpressionWithPattern:@"equilateral"
                                                                             options:NSRegularExpressionCaseInsensitive error:&regexError];
    if (!regexError)
    {
        NSArray *matches1 = [regex1 matchesInString:[attributedString string]
                                                options:0
                                                  range:NSMakeRange(0, [[attributedString string] length])];
        NSArray *matches2 = [regex2 matchesInString:[attributedString string]
                                                options:0
                                                  range:NSMakeRange(0, [[attributedString string] length])];

        for (NSTextCheckingResult *aMatch in matches1)
        {
            NSRange matchRange = [aMatch range];
            [attributedString setAttributes:@{NSFontAttributeName:boldFont}
                                      range:matchRange];
        }
        for (NSTextCheckingResult *aMatch in matches2)
        {
            NSRange matchRange = [aMatch range];
            [attributedString setAttributes:@{NSFontAttributeName:italicizedFont}
                                      range:matchRange];

        }

    [self.someLabel setAttributedText: attributedString];
like image 32
momodude22 Avatar answered Nov 01 '25 15:11

momodude22



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!