framework 中添加自定义字体

1,024 阅读2分钟

这是我参与更文挑战的第9天,活动详情查看: 更文挑战

在移动端开发的过程中,iconfont 出现的频率越来越多了。一些小的项目,开发人员完全可以在 iconfont 上建一个项目,自己挑选中意的图标,然后完成设计和编码的全部过程。

iconfont是由阿里巴巴团队制作的,功能强大,图标内容丰富的矢量图标库,

如何在主工程中使用 iconfont,可以查看官方帮助文档

但是,在做模块化开发,或者做制作单独的 framework 时,我们可能也想使用 iconfont 或者其他自定义的字体。这和在主工程中使用的过程并不相同。

解决方案是:首先需要注册我们的字体,然后在主工程的 bundle 中才可以使用 framework 中的字体。

开始之前,有两点需要注意:

  1. 需要在 framework 中配置,不需要修改主项目的任何内容;
  2. 不需要修改 framework 的 info.plist。(需要添加一个 UIAppFontkey 的 key,value 为字体名称数组)

下面为具体做法:

import Foundation
enum RegisterFontError: Error {
  case invalidFontFile
  case fontPathNotFound
  case initFontError
  case registerFailed
}
class GetBundle {}
extension UIFont {
static func register(path: String, fileNameString: String, type: String) throws {
  let frameworkBundle = Bundle(for: GetBundle.self)
  guard let resourceBundleURL = frameworkBundle.path(forResource: path + "/" + fileNameString, ofType: type) else {
     throw FontError.fontPathNotFound
  }
  guard let fontData = NSData(contentsOfFile: resourceBundleURL),    let dataProvider = CGDataProvider.init(data: fontData) else {
    throw FontError.invalidFontFile
  }
  guard let fontRef = CGFont.init(dataProvider) else {
     throw FontError.initFontError
  }
  var errorRef: Unmanaged<CFError>? = nil
 guard CTFontManagerRegisterGraphicsFont(fontRef, &errorRef) else   { 
       throw FontError.registerFailed
  }
 }
}

在 framework 中添加字体文件之后,就可以通过调用 UIFont.register(_:_:) 注册字体了。

注意:注册字体只能被调用一次。 实现起来也很简单,比如这样:

//Either lazy or static is ok
static var registerFonts: () -> Void = {
  UIFont.register(path:xxx, fileName: xxx, type: .ttf)

}()

然后调用 YourFont.resisterFonts就可以了。

可以通过下面的方法查看注册是否成功:

UIFont.familyNames.forEach { (font) in
    print("Family Name: \($0)")
    UIFont.fontNames(forFamilyName: $0).forEach({
        print("--Font Name: \($0)")
    })
}

参考

Add Font In Customize Framework Swift 4.2