The main way to show some text to the users is through
UILabels. Labels let us customize their text with some attributes. Most of us always use the same attributes to customize them.
NSAttributedString API’s offer so many customization possibilities that I took some time to explore them. In today’s article, I’d like to share them with everybody, showing how they behave so that, the next time, we could use the right attribute for the job.
The Base API
Starting from the basics, the first customization point is about changing fonts, font size, and colors. To do that, we need to define the strings to print and a couple of attributes.
NSAttributedString API comes from Objective-C, a world where typing isn’t as strict as in Swift. However, Swift helps us a bit by adding some type safety. For example, the keys of the attributes dictionary must be of the
In the code, we are creating a first string with the
Baskerville font, another with the
Chalkduster, increasing the font size and we are painting it orange. We can even change the background, setting it to blue. The result is the following:
Note: during the rest of the article, I will focus on the code of the attributes, reusing the
Adjusting the text
Then, there are a set of attributes that let us play with where the letters are rendered within the label. We can play with:
Here the code, with the corresponding attributes:
And this is the resulting effect:
The Subtle Difference Between Tracking and Kerning
As you can see, tracking and kerning look pretty similar to each other. Both of them work on the horizontal spacing of the text you are working with.
The main difference is that the kerning works at the letter level. It defines the distance between characters in the work. From Apple documentation:
Kerning prevents unwanted space from occurring between specific characters and depends on the font.
The tracking, instead, works at the word level. It is used to adjust homogeneously the characters within a word, to avoid unwanted spaces. The Apple documentation does not provide any extra useful information. However, I found this article useful to understand the difference.
Another customization let us add an underline or strike the text. We can change the color of the strike line and its style. However, even though there are several styles available, only some of them work with UIKit. These are
NSUnderlineStyle.thick. The various
dashDotDot does not seem to work, and neither the
byWord style does.
Bonus point for the last style: it allows you to specify a link and it shows the classic appearance of the links, with the custom text underlined. However, given that the
UILabel are not controls, the user won’t be able to tap on them… But you can still use the very same attributed string in a
UITextField or in a
UITextView to enable the tap!
Here the result of the above code. Notice how the
underlineColor attribute worked with the
link attribute as well.
Miscellaneous simple attributes
There is a bunch of other attributes that alter the appearance of the text. These are simple attributes: they require us to set a value for specific attributes and then they render the text differently.
These attributes are:
obliqueness: as the name implies, this attribute skews the letters by a factor we can specify.
effect: this attribute allows us to specify a letterpress effect that makes the letters look like they have been printed.
strokeWidth: these attributes color the contour of the text making it transparent inside. We need to specify both the color and the width of the stroke to obtain this effect.
Here the code with these attributes set:
And this is what we can see on the screen after applying them:
Shadows and Attachments
Moving to more complex attributes, we can do a couple of interesting things with our text.
First, we can add shadows under it. These shadows will follow the shape of the text and can deliver a stunning effect to the user. Here the sample code for that:
As for the other shadows in UIKit, we can control the
blurRadius and the
shadowOffset. All these properties are set in a
NSShadow object. The result is the following:
Finally, it is possible to add an attachment to the string. Imagine that you want to add a currency into your app, and you want a button that says
purchase 10 💎. You can do it with the attachments:
In this case, the process is slightly more complex. We need to:
- create an
- add the attachment to the attributes for the string
- create an
NSAttributedStringfor the attachment only
- create an
NSMutableAttributedStringwith the attributes which contain the attachment
- compose the two attributed strings
- finally set them into the label.
The result of this effort is pretty nice:
Today we explored what we can achieve with
NSAttributedStrings. There are a few more attributes that we skipped because they are very rare (the
writingDirection, for example, is usually handled by the system).
The big missing attribute is the
paragraphStyle: this object allows you to control many aspects of a paragraph, so how a multiline text behaves. For example, it can be used to control line spacing, indentation, and many other things. However, this attribute is slightly complex and it could require an article on its own.
Knowing all these details is really important to understand how the text works on iOS. Nonetheless, using this API is tedious and very error-prone. My suggestion is to use a library that can simplify a lot the
NSAttributedString’s customization and can make it easier to work with them. At Bending Spoons, we use BonMot for this purpose: if you are curious about what you can do with it, I strongly encourage you to click on the link and to give it a try!