Skip to content

Instantly share code, notes, and snippets.

@fcanas
Last active November 16, 2020 18:16
Show Gist options
  • Save fcanas/1c21e161ea6cbe7b1f9bb329721e4343 to your computer and use it in GitHub Desktop.
Save fcanas/1c21e161ea6cbe7b1f9bb329721e4343 to your computer and use it in GitHub Desktop.
Ordering Matters in UIFontDescriptor, a bug
import UIKit
/*:
# Ordering Matters in UIFontDescriptor
Oct 21, 2017, iOS 11
When creating a derived font descriptor with a font family, existing traits
such as italic or bold are overwritten or ignored.
*/
/*:
Here I attempt to build a font with an italic trait from the Avenir family.
*/
var wrongFontDescriptor = UIFontDescriptor()
wrongFontDescriptor = wrongFontDescriptor.withSymbolicTraits([.traitItalic])!
wrongFontDescriptor = wrongFontDescriptor.withFamily("Avenir")
/*:
The resulting font is "Avenir-Book", which is not what I would expect.
*/
var wrongFont = UIFont(descriptor: wrongFontDescriptor, size: 12)
wrongFont.fontName // "Avenir-Book"
/*:
If symbolic traits are added after the font family, the resulting font is as
expected.
*/
var rightFontDescriptor = UIFontDescriptor()
rightFontDescriptor = rightFontDescriptor.withFamily("Avenir")
rightFontDescriptor = rightFontDescriptor.withSymbolicTraits([.traitItalic])!
var rightFont = UIFont(descriptor: rightFontDescriptor, size: 12)
rightFont.fontName // "Avenir-BookOblique"
/*:
I would expect that setting the font family would not override traits
unecessarily. This would allow the construction of fonts from their
characteristics in any order.
Alternatively, I would expect the documentation for `UIFontDescriptor` to be
clear about the behavior of `-fontDescriptorWithFamily:`.
The documentation states only:
> Returns a new font descriptor whose attributes are the same as the receiver
> but from the specified family.
*/
/*:
## Additional Examples
The same can be shown for the Bold trait and combined traits.
Traits before family results in a wrong font:
*/
wrongFontDescriptor = UIFontDescriptor()
wrongFontDescriptor = wrongFontDescriptor.withSymbolicTraits([.traitBold])!
wrongFontDescriptor = wrongFontDescriptor.withFamily("Avenir")
wrongFont = UIFont(descriptor: wrongFontDescriptor, size: 12)
wrongFont.fontName // "Avenir-Book"
wrongFontDescriptor = UIFontDescriptor()
wrongFontDescriptor = wrongFontDescriptor.withSymbolicTraits([.traitBold, .traitItalic])!
wrongFontDescriptor = wrongFontDescriptor.withFamily("Avenir")
wrongFont = UIFont(descriptor: wrongFontDescriptor, size: 12)
wrongFont.fontName // "Avenir-Book"
/*:
Traits after family is correct
*/
rightFontDescriptor = UIFontDescriptor()
rightFontDescriptor = rightFontDescriptor.withFamily("Avenir")
rightFontDescriptor = rightFontDescriptor.withSymbolicTraits([.traitBold])!
rightFont = UIFont(descriptor: rightFontDescriptor, size: 12)
rightFont.fontName // "Avenir-Heavy"
rightFontDescriptor = UIFontDescriptor()
rightFontDescriptor = rightFontDescriptor.withFamily("Avenir")
rightFontDescriptor = rightFontDescriptor.withSymbolicTraits([.traitItalic, .traitBold])!
rightFont = UIFont(descriptor: rightFontDescriptor, size: 12)
rightFont.fontName // "Avenir-HeavyOblique"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment