4

The method I'm trying to use to get a bold faced iOS UIFont given a font family name only seems to work for some fonts. For example:

UIFont* font = [UIFont fontWithName:@"TimesNewRomanPS-BoldMT" size:12];
NSLog(@"A: Font name: %@", [font fontName]);

// desired method works for Helvetica Neue
UIFontDescriptor *desc = [[UIFontDescriptor alloc] init];
desc = [desc fontDescriptorWithFamily:@"Helvetica Neue"];
desc = [desc fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
font = [UIFont fontWithDescriptor:desc size:12];
NSLog(@"B: Font name: %@", [font fontName]);

// desired method fails for Times New Roman
desc = [[UIFontDescriptor alloc] init];
desc = [desc fontDescriptorWithFamily:@"Times New Roman"];
NSLog(@"desc: %@", desc);
desc = [desc fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
NSLog(@"desc bold: %@", desc);

prints (on iOS 8.1 simulator):

A: Font name: TimesNewRomanPS-BoldMT
B: Font name: HelveticaNeue-Bold
desc: UICTFontDescriptor <0x7f9be0d05e80> = { NSFontFamilyAttribute = "Times New Roman"; }
desc bold: (null)

Is this a bug, or is it not designed to work for every font family (which actually has a bold variant)? I really do not want to be forced to parse font names looking for "Bold" or some such thing.

devx
  • 307
  • 1
  • 14
  • I am another victim of this fontDescriptorWithSymbolicTraits: bug. It's a shame because it worked perfectly well with any font on iOS7. Did you find a clever workaround in the meantime? I don't want to parse font name for "-Black|-Bold|-Italic|-Oblique" me too. – Bluezen Jan 02 '15 at 19:07

2 Answers2

4

This is a bug. fontDescriptorWithSymbolicTraits: is guaranteed to return a font descriptor; returning nil is therefore unexpected behavior.

In fact, if you rewrite the same thing with Swift, it will cause a crash because desc isn't optional:

var desc = UIFontDescriptor()
desc = desc.fontDescriptorWithFamily("Times New Roman")
desc = desc.fontDescriptorWithSymbolicTraits(.TraitBold)
println(desc); //crash

Whether or not the UIFontDescriptor would return a UIFont is a separate question. You should file a radar.

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
  • Thanks! I submitted bug report 18812268 for this. – devx Oct 29 '14 at 17:17
  • @devx Did Apple ever address this? I've got the same issue. . – Micrified Dec 29 '15 at 21:13
  • 2
    This has changed, probably in iOS 10 SDK / Swift 2.3 / Xcode 8. If you look into `UIFontDescriptor` header, you will find this: `public func fontDescriptorWithSymbolicTraits(symbolicTraits: UIFontDescriptorSymbolicTraits) -> UIFontDescriptor? // Returns a new font descriptor reference in the same family with the given symbolic traits, or nil if none found in the system.` Therefore, fontDescriptorWithSymbolicTraits is no longer guaranteed to return a font descriptor. – Tom Kraina Sep 27 '16 at 07:29
1

@neural5torm offers a nice workaround to this iOS8 bug:

NSString *fontFamily = @"Arial";
BOOL isBold = YES;
BOOL isItalic = YES;
CGFloat fontSize = 20.0;
UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:
    @{
        @"NSFontFamilyAttribute" : fontFamily,
        @"NSFontFaceAttribute" : (isBold && isItalic ? @"Bold Italic" : (isBold ? @"Bold" : (isItalic ? @"Italic" : @"Regular")))
    }];
UIFont *font = [UIFont fontWithDescriptor:fontDescriptor size:fontSize];

Original post: https://stackoverflow.com/a/26222986/3160700

Community
  • 1
  • 1
Bluezen
  • 850
  • 9
  • 13