Question

I'm trying to figure out how to best bold and un-bold a UILabel with a font that was defined in the Interface Builder.

I know I can do this, for example:

[myLabel setFont:[UIFont boldSystemFontOfSize:14.0]];

But then I'm forcing the font to potentially different (both in style and size) than the way it was designed in IB.

I'm looking for something that essentially does this:

[myLabel setBold:TRUE];

or False, as the case may be.

Is there a way to do this?

Was it helpful?

Solution

Unfortunately, there's no real concept of "Bold" in UIKit. If you ever try setting part of an attributed string to "Bold", you are actually selecting the bold font variant in the same font family.

You could so something semihackish like this:

@implementation UIFont (BoldVariant)

- (UIFont *)boldVariant
{
    for (NSString *fontName in [UIFont fontNamesForFamilyName:self.familyName]) {
        if ([fontName hasSuffix:@"-Bold"]) {
            return [UIFont fontWithName:fontName size:self.pointSize];
        }
    }

    // If we couldn't find it, return the same font.
    return self;
}

@end

This assumes that the font follows the standard naming scheme. It also assumes that fontNamesForFamilyName: returns any values. I noticed that with the system font, it returns an empty array.

OTHER TIPS

If you are using for example system font which is Helvetica you can make the label.text bold like this:

myLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:14];

You can find iOS fonts for example in this site: link

You want an approach that works regardless of the font that is in place in your label, so it works with multiple labels?

How about this?

Fetch the current font from the label using it's font property.

Get the font family name for that font.

Ask the font family for it's list of fonts using the UI fontNamesForFamilyName.

See if you can find a bold font in the list of fonts you get back. If so, request that font at your current font size. If not, use the bold system font at the current size. (You might have to string parse the font names looking for the word "bold" in the name. Ugh.)

Not ideal, but you should be able to make it work.

I was able to find nice and clear solution:

extension UIFont {

    /// Returns same font but with specific `symbolicTraits`.
    func with(symbolicTraits: UIFontDescriptor.SymbolicTraits) -> UIFont {
        let descriptor = fontDescriptor.withSymbolicTraits(symbolicTraits) ?? fontDescriptor
        return UIFont(descriptor: descriptor, size: pointSize)
    }
}

Usage:

label.font = label.font.with(symbolicTraits: .traitBold)

Or if you want to mix multiple traits:

label.font = label.font.with(symbolicTraits: [.traitBold, .traitItalic) // returns same font (name and size) but is bold and italic.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top