Different fonts for the same label

:  ~ 1 min read

Been slacking lately, but I hope I can make it up with this one. Let's say you need to display a price, and the currency, but the currency code should have a different font. You could have two labels, but that just complicates code and brings unwanted overhead, so let's use the same label.

This part will be common to all examples:

let priceFont = UIFont(name: "CustomFontBold", size: 15)

// This is the part we will work on in the next steps.
let currencyFont = [...]

let attributedPrice = NSMutableAttributedString(string: price,
  attributes: [
    .font: priceFont,
    .foregroundColor: UIColor.darkText
  ]
)

attributedPrice.addAttribute(.font,
  value: currencyFont,
  range: NSMakeRange(0, 3)
)

[...] // Last step would go here.

Easiest task - same family, same size, different weight:

let currencyFont = UIFont(
  name: "CustomFontRegular",
  size: priceFont.pointSize // Just add / subtract if needed
)

A bit more complex - same family, same weight, different size (we will make use of a previously mentioned technique):

let currencyFont = UIFont(
  name: priceFont.fontName,
  size: priceFont.pointSize - 2
)

The trickiest - same as above, but it will be aligned to the top, so we will need to add the following:

attributedPrice.addAttribute(.baselineOffset,
  value: priceFont.capHeight - currencyFont.capHeight,
  range: NSMakeRange(0, 3)
)

As a bonus for the last example, in the case where we don't want all-caps for the currency (thus b will have a different height than a), I usually adjust for optical illusions where needed:

attributedPrice.addAttribute(.baselineOffset,
  value: priceFont.capHeight - currencyFont.capHeight + someOffset,
  range: NSMakeRange(0, 3)
)
![Unadjusted](/images/adjusted-labels/unadjusted.png) ![adjusted](/images/adjusted-labels/adjusted.png)

Unadjusted vs adjusted - maybe I'm wrong, but I find the adjusted one slightly more pleasing to the eye.

Merry Christmas, everybody!