4

UIFont provides the +preferredFontForTextStyle: method to get a font instance with the proper size based on the user's selected content size category and the given UIFontTextStyle.

What I would like to do is get a font for a given text style and content size. Something like +fontForContentSizeCategory:andTextStyle:.

Unfortunately I cannot find anything similar to that in the headers for UIFont or UIFontDescriptor.

Any idea on how to achieve this?

Thanks

mokagio
  • 16,391
  • 3
  • 51
  • 58

2 Answers2

6

Unfortunately, both +[UIFont preferredFontForTextStyle:] and +[UIFontDescriptor preferredFontDescriptorWithTextStyle:] rely on -[UIApplication preferredContentSizeCategory] internally. They use a private function _CTFontDescriptorCreateWithTextStyle to retrieve a CoreText font descriptor with specific text style and size category, and that's eventually based on a category → size mapping from the configuration file CoreTextConfig.plist stored somewhere, but I assume you wouldn't want to use private APIs.

While hesitantly implying a possibility to dynamically swizzle -[UIApplication preferredContentSizeCategory] to trick +[UIFontDescriptor preferredFontDescriptorWithTextStyle:] into returning a font descriptor for the size class you want, I can't recommend any specific approach to this. You can retrieve a font descriptor like this:

let descriptor = UIFontDescriptor(fontAttributes: [ UIFontDescriptorTextStyleAttribute : UIFontTextStyleBody ])

but it won't contain a size attribute, so you would be left with trying to come up with a category → size mapping yourself.

Vlas Voloshin
  • 543
  • 1
  • 7
  • 21
5

Since iOS 10.0 this is possible using UITraitCollection:

let traitCollection = UITraitCollection(preferredContentSizeCategory: contentSizeCategory)
let font = UIFont.preferredFont(forTextStyle: textStyle, compatibleWith: traitCollection)
Marco
  • 330
  • 5
  • 13