5

Having a UILabel with any font, how can I find out if it is already bold? Or how can I make it bold? In CSS, I have a font-weight attribute. I would like to have something similar.

Everything I found out so far is that you have to set the proper font name. However, this is unreliable. The bold version of Cochin is Cochin-Bold, but the bold version of ArialMT is not ArialMT-Bold but Arial-BoldMT, so it obviously does not suffice to append -Bold. (The bold version of a custom font could also have a totally different name).

What I can do is finding all fonts for the family of my given font.

__block UIFont *font = myLabel.font;
[[UIFont fontNamesForFamilyName:font.familyName] enumerateObjectsUsingBlock:^(NSString *fontName, NSUInteger idx, BOOL *stop) {
    if ([fontName rangeOfString:@"bold" options:NSCaseInsensitiveSearch].location != NSNotFound) {
        font = [UIFont fontWithName:fontName size:font.pointSize];
        *stop = YES;
    }
}];
myLabel.font = font;

But this does not work reliably. I can easily get a BoldItalic version. I could improve my check to avoid this, but it is not really a good solution.

Maybe CoreText can help here?

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
Björn Landmesser
  • 953
  • 10
  • 26

3 Answers3

10

Maybe CoreText can help here?

CoreText uses its own font system, CTFont. If you're using that, you can do what you want:

CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)name, size, NULL);
CTFontRef boldFont = CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, kCTFontBoldTrait, kCTFontBoldTrait);

I suppose you could then get the name of the derived bold font:

CFStringRef boldName = CTFontCopyPostScriptName(boldFont);

...and use it to create a new UIFont:

UIFont *ret = [UIFont fontWithName:(NSString *)boldName size:size];

I don't know how quick this would be, but you could do it on app launch then cache the names.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Amy Worrall
  • 16,250
  • 3
  • 42
  • 65
  • Thanks a lot! I just found [this article](http://stackoverflow.com/questions/7492237/objective-c-ctfont-change-font-style) which has a similar solution. I tried to play with variation axes, but that is really not documented very well. – Björn Landmesser Dec 16 '11 at 12:56
  • 3
    one little thing: `CTFontCopyFullName` yields e.g. `"American Typewriter Bold"`, but I want `"AmericanTypewriter-Bold"`. To get the right name I have to use `CFStringRef boldName = CTFontCopyName(boldFont, kCTFontPostScriptNameKey)` – Björn Landmesser Dec 16 '11 at 13:04
  • 2
    Late entry here, but you can also get the PostScript name with the function `CTFontCopyPostScriptName`. This should be corrected in the answer, since it doesn't work as posted. – warrenm Jan 02 '13 at 22:17
  • Thanks for the edit! Since I posted this answer, `UIFontDescriptor` was introduced, which makes this process a lot easier. I'll post a new answer. – Amy Worrall Mar 06 '17 at 11:29
1

Introduced with iOS 7, UIFontDescriptor is the tool for doing this.

To find out if the font is already bold, get the UIFontDescriptor of your font (via UIFont's fontDescriptor property), then call symbolicTraits, and inspect the resulting bitmask for UIFontDescriptorTraitBold.

Likewise, to find a bold version, take the font descriptor for the original font, and call - fontDescriptorWithSymbolicTraits:. You can then turn it back into a UIFont by calling + [UIFont fontWithDescriptor:size:].

Amy Worrall
  • 16,250
  • 3
  • 42
  • 65
1

UIFontDescriptorSymbolicTraits symbolically describes stylistic aspects of a font. The upper 16 bits is used to describe appearance of the font whereas the lower 16 bits for typeface. The font appearance information represented by the upper 16 bits can be used for stylistic font matching.

Swift 3

extension UIFont {
    convenience init?(name: String, size: CGFloat, symbolicTraits: UIFontDescriptorSymbolicTraits) {
        guard let descriptor = UIFontDescriptor(name: name, size: size).withSymbolicTraits(symbolicTraits) else { return nil }
        self.init(descriptor: descriptor, size: size)
    }
}
Madmoron
  • 188
  • 2
  • 4