I found a way to solve this problem through method swizzling. Following are steps to solve this problem:
- Step1: Create an extension of UIFont and the following code to override font name and family runtime.
Code Example:
var appFontName = "ArialMT"
var appFontBoldName = "Arial-BoldMT"
extension UIFontDescriptor.AttributeName {
static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
}
extension UIFont {
@objc class func mySystemFont(ofSize size: CGFloat) -> UIFont {
return UIFont(name: appFontName, size: size)!
}
@objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont {
return UIFont(name: appFontBoldName, size: size)!
}
@objc convenience init(myCoder aDecoder: NSCoder) {
guard let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor else {
self.init(myCoder: aDecoder)
return
}
let face = fontDescriptor.object(forKey: UIFontDescriptor.AttributeName.face) as? String ?? "Regular"
var fontName = appFontName
switch face {
case "Regular":
fontName = appFontName
case "Bold":
fontName = appFontBoldName
default:
fontName = appFontName
}
self.init(name: fontName, size: fontDescriptor.pointSize)!
}
class func overrideInitialize() {
if self == UIFont.self {
let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:)))
let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:)))
method_exchangeImplementations(systemFontMethod!, mySystemFontMethod!)
let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:)))
let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:)))
method_exchangeImplementations(boldSystemFontMethod!, myBoldSystemFontMethod!)
let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:)))
let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:)))
method_exchangeImplementations(initCoderMethod!, myInitCoderMethod!)
}
}
}
It preserves Font size by changing font family throughout your app. :)