Easy UIFont Bold and Italic Trait Querying

With the arrival of some neat new libraries I can’t talk about yet, I wanted a convenient way to ask a UIFont instance if it was bold or italic*. Although there’s no direct route as there is with NSFont on Mac OS, It turns out it’s relatively easy to add this functionality to UIFont via an Objective-C category.

The following category will add -isBold and -isItalic methods to UIFont. It targets iOS 6 but the example uses public knowledge about iOS and Mac OS in addition to publicly-announced upcoming developer features in iOS 6.**

The header (UIFont+Traits.h):

#import 
#import 

@interface Traits

-(CTFontSymbolicTraits)traits;
-(BOOL)isBold;
-(BOOL)isItalic;

@end

And the implementation (UIFont+Traits.m):

#import "UIFont+Traits.h"

@implementation UIFont (Traits)

-(CTFontSymbolicTraits)traits
{
    CTFontRef fontRef = (__bridge CTFontRef)self;
       CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef);
       return symbolicTraits;
}

-(BOOL)isBold
{
    CTFontSymbolicTraits symbolicTraits = [self traits];
    return (symbolicTraits & kCTFontBoldTrait);
}
        
-(BOOL)isItalic
{
    CTFontSymbolicTraits symbolicTraits = [self traits];
    return (symbolicTraits & kCTFontItalicTrait);
}

@end

The secret sauce is in CoreText.framework (which you’ll have to link). The -traits method will fetch any font trait (useful beyond my case), and the rest of the convenience methods rely on it. Feel free to build it out and share your own additions. The sharp-eyed will also notice I’m using ARC memory management in -traits.

It also occurs to me the value from -traits could be cached in an NSNumber object using objc\_setAssociatedObject() and objc\_getAssociatedObject(). Since the created font’s traits shouldn’t change*** (you have to create a new font instance of the family with the desired traits), this may speed up many successive calls to CoreText. This way you can ask once for its traits (via -isBold, for example), then successive calls (via -isItalic, for another example) would not need to ask CoreText again for the life of the UIFont instance.

Happy coding!


* There is no such thing as an “underline font trait,” so make sure you look for NSUnderlineAttributeName if you want to find underlined text.

** At the time of this writing, iOS 6 is under nondisclosure agreement. Fortunately the fact ARC is going to be in iOS 6 is public knowledge. Everything else will work on iOS 5. Just beware of symbol name updates in 6.

*** I haven’t verified this assumption, which is why I haven’t included caching in the category. I’m not entirely sure none of a UIFont instance’s traits would never change during its life. I’d love to hear from the community on that one.

Josh