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.