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:
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