Localized font list

Looking for a solution for enumerating all available fonts in iOS most of the answers points to the UIFont‘s familyNames and fontNamesForFamilyName methods. The problem with these methods is, that the strings returned are not really suitable for a presentation in the user interface. Furthermore fontNamesForFamilyName returns the full qualified name of a font, including its style, which is good for creating a font with the fontWithName initializer, but again not really suitable for presentation. Looking into UIFont‘s reference it seems kind of an hack to get the style names. One should extract the family name from the full name of the font, which in some cases would also lead to unpredictable results. But no panic! The solution is very close, just one level deeper in the CoreText library. The key function for reading the font families and styles individually is CTFontCopyLocalizedName. It takes a CTFontRef font reference, a name key, which defines the attribute to read out and a reference for writing the current language into. In addition to get the isolated style name, you also get a localized version of the font family and style names. Two keys are important for our purposes:

  1. kCTFontFamilyNameKey, and
  2. kCTFontStyleNameKey

The key kCTFontFamilyNameKey gets the localized name of the font family. Basically the localized font family names contains spaces between single words so that instead of writing “HelveticaNeue”, the user gets “Helvetica Neue” which is better suited for presentation. The key kCTFontStyleNameKey provides the localized name of the font’s style without the family name. The result is a localized description of the style like “Regular”, “Thin”, “Ultra thin”, which is again better suited for presentation. In fact the function is so fundamental, that I decided to build a category on UIFont for my purposes, see the listing below:

Here the header for completeness:

Also notice the __bridge_transfer keyword, which transfers the memory ownership of the string reference returned by the function CTFontCopyLocalizedName to ARC. The other references should of course be released to avoid memory leaks. With that category it is very easy to write a view controller which presents the font list to the user. Here an example for handling the list of localized family names in a table view controller:

The font families are read into a static class array which is reused during the lifecycle of the app. In cellForRowAtIndexPath a UIFont object is created, using the font family corresponding to the given index path. The method localizedFamilyName is called to get the localized name of the font family to be assigned to the cell’s label. The font created is also used to show the font family appearance to the user, which leads to a very nice presentation. The original family names are created via the well known UIFont method during the view loading.

The view controller for style selection is similar. The selected font is passed from the font families view controller to the style list view controller in order to provide the related styles:

This time the available font styles are stored into an array property of the view controller, static doesn’t make sense, since this list must be created every time the calling controller changes the font family. Again a font is created and it’s localized style is derived by the corresponding UIFont localizing category method localizedStyleName. The font is used to show it’s appearance in the table view here as well. The selected style is passed back to the family view controller via a delegate call, which is basic view controller handling and therefore not in the scope of this article.

One step deeper from UIKit into CoreText gave us a powerful method to present localized font names on a nifty user interface. One may ask, why did the Apple guys not simply extend UIFont to this capability? Well, there must always be space for improvements and challenges to face for an app programmer and … there are categories!

nifty_fonts