Set a default font for whole iOS app? Set a default font for whole iOS app? ios ios

Set a default font for whole iOS app?


It seems to be possible in iOS 5 using the UIAppearance proxy.

 [[UILabel appearance] setFont:[UIFont fontWithName:@"YourFontName" size:17.0]];

That will set the font to be whatever your custom font is for all UILabels in your app. You'll need to repeat it for each control (UIButton, UILabel, etc.).

Remember you'll need to put the UIAppFonts value in your info.plist and include the name of the font you're including.


Swift 5

Base on Fábio Oliveira's answer (https://stackoverflow.com/a/23042694/2082851), I make my own swift 4.

In short, this extension exchanges default functions init(coder:), systemFont(ofSize:), boldSystemFont(ofSize:), italicSystemFont(ofSize:) with my custom methods.

Note that it's not fully implement, but you can exchange more methods base on my implementation.

import UIKitstruct AppFontName {    static let regular = "CourierNewPSMT"    static let bold = "CourierNewPS-BoldMT"    static let italic = "CourierNewPS-ItalicMT"}extension UIFontDescriptor.AttributeName {    static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")}extension UIFont {    static var isOverrided: Bool = false    @objc class func mySystemFont(ofSize size: CGFloat) -> UIFont {        return UIFont(name: AppFontName.regular, size: size)!    }    @objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont {        return UIFont(name: AppFontName.bold, size: size)!    }    @objc class func myItalicSystemFont(ofSize size: CGFloat) -> UIFont {        return UIFont(name: AppFontName.italic, size: size)!    }    @objc convenience init(myCoder aDecoder: NSCoder) {        guard            let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor,            let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String else {                self.init(myCoder: aDecoder)                return        }        var fontName = ""        switch fontAttribute {        case "CTFontRegularUsage":            fontName = AppFontName.regular        case "CTFontEmphasizedUsage", "CTFontBoldUsage":            fontName = AppFontName.bold        case "CTFontObliqueUsage":            fontName = AppFontName.italic        default:            fontName = AppFontName.regular        }        self.init(name: fontName, size: fontDescriptor.pointSize)!    }    class func overrideInitialize() {        guard self == UIFont.self, !isOverrided else { return }        // Avoid method swizzling run twice and revert to original initialize function        isOverrided = true        if let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:))),            let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:))) {            method_exchangeImplementations(systemFontMethod, mySystemFontMethod)        }        if let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:))),            let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:))) {            method_exchangeImplementations(boldSystemFontMethod, myBoldSystemFontMethod)        }        if let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:))),            let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:))) {            method_exchangeImplementations(italicSystemFontMethod, myItalicSystemFontMethod)        }        if let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))), // Trick to get over the lack of UIFont.init(coder:))            let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:))) {            method_exchangeImplementations(initCoderMethod, myInitCoderMethod)        }    }}class AppDelegate: UIResponder, UIApplicationDelegate {    // Avoid warning of Swift    // Method 'initialize()' defines Objective-C class method 'initialize', which is not guaranteed to be invoked by Swift and will be disallowed in future versions    override init() {        super.init()        UIFont.overrideInitialize()    }    ...}


There is also another solution which will be to override systemFont.

Just create a category

UIFont+SystemFontOverride.h

#import <UIKit/UIKit.h>@interface UIFont (SystemFontOverride)@end

UIFont+SystemFontOverride.m

@implementation UIFont (SystemFontOverride)#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"+ (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize {    return [UIFont fontWithName:@"fontName" size:fontSize];}+ (UIFont *)systemFontOfSize:(CGFloat)fontSize {    return [UIFont fontWithName:@"fontName" size:fontSize];}#pragma clang diagnostic pop@end

This will replace the default implementation and most UIControls use systemFont.