如何在整个 IOS 应用程序中以正确的方式使用自定义字体

How to use a custom font in an entire IOS app the right way

我已经对这个主题进行了大量调查,但是,我还没有找到一种方法来轻松地为整个 IOS 应用程序设置自定义字体.我需要为一个非常大的应用程序更改整个字体,我已经在 Android.

中轻松完成了

解决方案的答案似乎对于 objective-C 来说已经过时,或者 对于这个任务来说太复杂了

到目前为止,我已经找到 3 种主要 方法:

  1. Traditional approach: 使用枚举或扩展。问题是,如果应用程序已经很先进,那么将字体应用于每个视图真的很乏味。
  2. 。问题是它将字体设置为每个单独的视图,您可能希望有一个 UILabel 使用一种字体,另一个使用其他字体。
  3. Using a "Hack"(似乎是一个很好的解决方案)问题是它有风险而且不是未来的证明,因为将来苹果可能会在应用商店中拒绝这样的应用。这种方法也改变了一些系统 UI 字体,因此它更像是一种 hack 而不是本机解决方案。

这些解决方案是我找到的,但它们并不完全灵活。 Android has a great way to do it只需在xml和tadaa中添加一个字体系列,系统会自动选择合适的),我相信IOS可能会有。

还有其他办法吗?否则,推荐的方法是什么

您可以阅读这篇文章: Set default custom font for entire app – Swift 5

或者你可以使用这个:

Fonts.swift

将 swift 文件导入项目后,只需更改此行中的默认字体: class var defaultFontFamily: String { return "Georgia" }

要使用它,您必须在 AppDelegatedidFinishLaunchingWithOptions 方法中注册 class 使用:

UIFont. initialize()

this site的基础上做一些调整

首先:你必须在你的项目中添加你的字体,并将它们添加到info.plist文件中: https://codewithchris.com/common-mistakes-with-adding-custom-fonts-to-your-ios-app/

文件:UIFont.swift

import Foundation
import UIKit

struct AppFontName {
  static let regular = "Montserrat-Regular"
  static let bold = "Montserrat-Bold"
  static let lightAlt = "Montserrat-Light"
}
//customise font
extension UIFontDescriptor.AttributeName {
  static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
}

extension UIFont {

  @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.lightAlt, 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.lightAlt
    default:
        fontName = AppFontName.regular
    }
    self.init(name: fontName, size: fontDescriptor.pointSize)!
  }

  class func overrideInitialize() {
    guard self == UIFont.self else { return }

    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)
    }
  }
}

AppDelegate.swift

override init() {
    super.init()
    UIFont.overrideInitialize()
}

用法:

label.font = UIFont.boldSystemFont(ofSize: 16)
label.fontUIFont.systemFont(ofSize: 12)