iosobjective-cnsstringnsmutableattributedstring

How to apply bold and italics to an NSMutableAttributedString range?


I've been trying to apply combinations of NSFontAttributes to NSMutableAttributedString's lately and I simply can't find a thorough explanation on how to do it without removing other attributes.

I've searched a bunch, and found this question pertaining to how to do it with HTML, and then this question about how to find where text has been bolded or italicized, but nothing on how to actually do it.

Currently, I try to format stings as follows:

Italics: [mutableAttributedString addAttribute: NSFontAttributeName value:[fontAttributes valueForKey:CXItalicsFontAttributeName] range:r];

Bold: [mutableAttributedString addAttribute:NSFontAttributeName value:[fontAttributes valueForKey:CXBoldFontAttributeName] range:r];

Where the constants CXItalicsFontAttributeName and CXBoldAttributeName extract the following two values from a dictionary respectfully:

UIFont *italicsFont = [UIFont fontWithName:@"Avenir-BookOblique" size:14.0f];
UIFont *boldFont = [UIFont fontWithName:@"Avenir-Heavy" size:14.0f];

I know this mustn't be the right way to go about formatting, as the NSAttributedString standard attributes don't include a ItalicsFontAttribute or BoldFontAttribute, but I can't find the properly way to do this. Can anyone assist me?


Solution

  • If you're applying each (bold or italic) trait individually, you need to make sure that bold and italic ranges don't overlap or one trait will overwrite the other.

    The only way to apply both bold and italic traits to a range is to use a font which is both bold and italic, and apply the both traits at once.

    let str = "Normal Bold Italics BoldItalics"
    
    let font = UIFont(name: "Avenir", size: 14.0)!
    let italicsFont = UIFont(name: "Avenir-BookOblique", size: 14.0)!
    let boldFont = UIFont(name: "Avenir-Heavy", size: 14.0)!
    let boldItalicsFont = UIFont(name: "Avenir-HeavyOblique", size: 14.0)!
    
    let attributedString = NSMutableAttributedString(string: str, attributes: [NSFontAttributeName : font])
    attributedString.addAttribute(NSFontAttributeName, value: boldFont, range: NSMakeRange(7, 4))
    attributedString.addAttribute(NSFontAttributeName, value: italicsFont, range: NSMakeRange(12, 7))
    attributedString.addAttribute(NSFontAttributeName, value: boldItalicsFont, range: NSMakeRange(20, 11))
    

    enter image description here