Why is applyFontTraits missing from UIKit?

On macOS, NSMutableAttributedString has the function applyFontTraits, which allows you to easily add or remove bold and italics from the attributed string (or a substring of it), but this function is missing from UIKit, and always has been. This is very strange, because it's trivial to add this back in via an extension on NSMutableAttributedString in UIKit.

Is there an explanation for why this isn't included in UIKit? What's the thinking here?

In case anyone needs it, this code adds this functionality back into UIKit:

Code Block swift
#if canImport(UIKit)
import UIKit
public struct NSFontTraitMask: OptionSet {
  public let rawValue: Int
  public static let boldFontMask = NSFontTraitMask(rawValue: 1 << 0)
  public static let unboldFontMask = NSFontTraitMask(rawValue: 1 << 1)
  public static let italicFontMask = NSFontTraitMask(rawValue: 1 << 2)
  public static let unitalicFontMask = NSFontTraitMask(rawValue: 1 << 3)
  public static let all: NSFontTraitMask = [.boldFontMask, .unboldFontMask, .italicFontMask, .unitalicFontMask]
  public init(rawValue: Int) {
    self.rawValue = rawValue
  }
}
extension NSMutableAttributedString {
  public func applyFontTraits(_ traitMask: NSFontTraitMask, range: NSRange) {
    enumerateAttribute(.font, in: range, options: [.longestEffectiveRangeNotRequired]) { (attr, attrRange, stop) in
      guard let font = attr as? UIFont else { return }
      let descriptor = font.fontDescriptor
      var symbolicTraits = descriptor.symbolicTraits
      if traitMask.contains(.boldFontMask) {
        symbolicTraits.insert(.traitBold)
      }
      if symbolicTraits.contains(.traitBold) && traitMask.contains(.unboldFontMask) {
        symbolicTraits.remove(.traitBold)
      }
      if traitMask.contains(.italicFontMask) {
        symbolicTraits.insert(.traitItalic)
      }
      if symbolicTraits.contains(.traitItalic) && traitMask.contains(.unitalicFontMask) {
        symbolicTraits.remove(.traitItalic)
      }
      guard let newDescriptor = descriptor.withSymbolicTraits(symbolicTraits) else { return }
      let newFont = UIFont(descriptor: newDescriptor, size: font.pointSize)
      self.addAttribute(.font, value: newFont, range: attrRange)
    }
  }
}
#endif


I've documented many of the different typographic features of San Francisco font, and have a library to allow using them very easy:

https://github.com/djfitz/SFFontFeatures

See below for a list of features that I support.

Doug Hill



Straight-sided six and nine
Open Four
Vertically Centered Colon
High Legibility
One Story a
Upper Case Small Capitals
Lower Case Small Capitals
Contextual Fractional Forms
Monospaced/Proportional Numbers
Superiors/Superscripts
Inferiors/Subscripts
Why is applyFontTraits missing from UIKit?
 
 
Q