【问题标题】:How to use a custom font in an entire IOS app the right way如何以正确的方式在整个 IOS 应用程序中使用自定义字体
【发布时间】:2020-09-30 15:15:25
【问题描述】:

我在这个话题上做了很多调查,但是,我还没有找到一种方法来轻松地为整个 IOS 应用设置自定义字体。我需要为一个非常大的应用程序更改整个字体,我已经在 Android 中非常轻松地做到了。

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

到目前为止,我已经找到了 3 种主要的 方法来做到这一点:

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

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

还有其他方法吗?或者,推荐的方法是什么

【问题讨论】:

  • 据我回忆,在完全重塑应用程序时,使用 .appearance() 看起来是最好的主意。您可以将所有外观定位在一个文件中,以便将来更轻松地在所有应用程序之间进行更改。使用 UIAppearance,您可以定义何时应用主题的规则(例如,如果包含在 UITableViewCell 中,则仅适用于 UILabel)

标签: ios swift xcode fonts


【解决方案1】:

基于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)

【讨论】:

  • 谢谢@MrMins 我想这样的事情是最好的选择。我希望苹果让它更简单!
  • @PedroAntonio 对,也许最简单的方法是覆盖 systemFont 方法。
  • 但您认为应用商店安全吗?我从未使用过方法调配
  • 是的@PedroAntonio,是完全安全的,我有一些应用程序商店使用代码批准的项目。此外,所有swift 版本的代码都非常相似,因此很容易更新
  • 您好,感谢您的出色解决方案。但这种方法也覆盖了pickerview字体。并且选择器视图中的文本显示不正确,因为我们使用不同的字体而不是 systom 字体。
【解决方案2】:

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

或者你可以使用这个:

Fonts.swift

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

要使用它,您必须在 AppDelegatedidFinishLaunchingWithOptions 方法中使用以下方法注册该类:

UIFont. initialize()

【讨论】:

    猜你喜欢
    • 2013-10-22
    • 1970-01-01
    • 2020-12-05
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 2011-11-28
    • 1970-01-01
    相关资源
    最近更新 更多