Tech Blog

Problematic: For some iOS application that I worked on, I had to use specific fonts and I encountered 2 issues doing so:

- The vertical offset can be too high or too low and the text is misaligned

- For a specific case I have to replace a specific glyph with another

I looked for different mac software to edit fonts and achieve this and I did not find one that was able to edit and save the font in it's original format for a reasonable price.

During my researches I found Apple Font Tool Suite a command line tool that can do that by extracting the font infos into an XML file. Then it's possible to edit these properties into the XML file and reintegrate this back into the font.

A font contains different tables representing glyphs, metrics, character mapping, ligature, kerning... The list of all tables is available here.

The command that is used to extract/fuse infos is called ftxdumperfuser, here is the parameters that we will use:

- '-t' (--table) Followed by the four character tag for the table to dump or fuse

- '-A d' to dump the table into an XML file

- '-A f' to fuse the XML data into the font

1. Replace glyph into a font

I'm working with the font Futura.ttc which contains 4 variants:

- Condensed ExtraBold

- Condensed Medium

- Medium Italic

- Medium

In this case you will got an XML output for each variants.

What I will do here, is replace the lowercase glyphs with the uppercase glyphs. (We have an app that share the same code base for different clients, and one of our clients asked us for a version with the Futura font that use uppercase everywhere in the app).

To achieve this we will replace the glyph data and update the metric (the new glyph can take more or less space).

These 3 screenshots are showing:

- The original font in lowercase

- The modified font just be replacing lowercase glyphs with uppercase glyphs

Problematic:I created a custom iOS component to display scores with an icon associated to what it represent. Now I have the need to customize the appearance of this component throughout my application.

My component KWIllustratedLabel is a UILabel subclass that just add an icon on the left and a gradient background with a border, as show in the following.

The KWIllustratedLabel can be used to display two different kind of scores into the application:

Points which represent the user experience, are in yellow with a lightning bolt.

Credits that the user win in the game and can be spent, represented in green with a money bag.

There is also some convenient methods and properties to keep these labels consistent across the application. Here is an extract from the header file.

Everything is drawn with vectors and can be resized, but that's not the subject here. What we want is to offer more flexibility for the pictograms, so we are providing an alternative artwork for each label type:

Points we can have a star instead of the lightning bolt

Credits can hide our company logo on the money bag

To achieve this I added a Boolean named useAlternativeIcon that will enable the usage of the new icon depending on the type of the label.

1. Customize properties with UIAppearence

To add support UIAppearance with our custom component we need to:

Subclass UIView (conforms to the UIAppearance protocol)

Expose style attributes as properties and tag them with the UI_APPEARANCE_SELECTOR macro

My class is a UILabel subclass so it also inherit from UIView, by adding the macro on this new attribute we get UIApparence working for free!

But what if we want to use the alternative artwork only for a specific type of illustrated label. Let's say for the Points but not for the Credits for example. It could be useful to be able to specify a parameter that will define when to apply the appearance.

2. Customize parametrized properties (i.e. use alternative artwork only for a specific type)

The documentation is really brief for this, it just says "To participate in the appearance proxy API, tag your appearance property accessor methods in your header with UI_APPEARANCE_SELECTOR."

I followed this and created the methods as you can see below. But then the documentation does not specify how to implement them and when these methods are called by the framework. After some research I found that the setter is called just before your view is added to the window and layout it's content.

/**
* Defines the label icon appearance for a specific `KWIllustratedLabelType`.
* @param illustratedLabelType The type of illustrated label that we want to set the alternative representation for.
*/
- (void)setUseAlternativeIcon:(NSNumber *)useAlternativeIcon forLabelType:(KWIllustratedLabelType)illustratedLabelType UI_APPEARANCE_SELECTOR;
/**
* Returns a boolean that indicates if the label icon appearance is specific for a given `KWIllustratedLabelType`.
* @param illustratedLabelType The type of illustrated label that we want to get the alternative representation from.
* @return A number representing a boolean indicating if the label use the alternative representation or not.
*/
- (NSNumber *)useAlternativeIconForLabelType:(KWIllustratedLabelType)illustratedLabelType UI_APPEARANCE_SELECTOR;

You can just save that value in an NSDictionary for example, so you have the value when you draw your views or if the getter gets called later. The internal implementation is really straight forward. Here is the implementation for the getter/setter with the axis and an internal getter for the property that takes care about the setting provided by the proxy.