提问者:小点点

资产目录中字体资产的定义是什么?


从iOS 13开始,CTFontManager具有以下功能:

@discussion Font assets are extracted from the asset catalog and registered. This call must be made after the completion handler of either NSBundleResourceRequest beginAccessingResourcesWithCompletionHandler: or conditionallyBeginAccessingResourcesWithCompletionHandler: is called successfully.
Name the assets using Postscript names for individual faces, or family names for variable/collection fonts. The same names can be used to unregister the fonts with CTFontManagerUnregisterFontDescriptors. In iOS, fonts registered with the persistent scope are not automatically available to other processes. Other process may call CTFontManagerRequestFonts to get access to these fonts.

@param      fontAssetNames
            Array of font name assets in asset catalog.

...

CTFontManagerRegisterFontsWithAssetNames(_ fontAssetNames: CFArray, _ bundle: CFBundle?, _ scope: CTFontManagerScope, _ enabled: Bool, _ registrationHandler: ((CFArray, Bool) -> Bool)?)

然而,资产目录没有任何方式添加“字体资产”。

我试过的:

  • 在此处取字体kanitregular.ttf(后记名称为kanit-regular)。
  • 在资产目录中创建了名为kanit-regular的数据资产。
  • 将字体文件重命名为kanit-regular.ttf并将其放入数据资产。

数据资产的contents.json现在如下所示:

{
   "data" : [
    {
      "filename" : "Kanit-Regular.ttf",
      "idiom": "universal",
      "universal-type-identifier" : "public.truetype-ttf-font"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
  • 尝试通过CTFontManager
  • 加载此字体

像这样:

func registerFont() {
    var cfBundle: CFBundle?
    if let bundle = Bundle(for: type(of: self)) {
        cfBundle = CFBundleCreate(kCFAllocatorDefault, bundle.bundleURL as CFURL)
    }
    CTFontManagerRegisterFontsWithAssetNames(["Kanit-Regular"] as CFArray, cfBundle, .persistent, true) { (errors, done) -> Bool in
        print(errors)
        return done
    }
}

在此之后,打印错误

▿ 1 element
  - 0 : Error Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" UserInfo={CTFontManagerErrorFontAssetNameKey=(
    "Kanit-Regular"
)}

有什么办法让它起作用吗?


共1个答案

匿名用户

通过以下操作使其工作:

  • 使用字体按需资源标记来标记KANIT-Regular数据资产(标记名称可以是您首选的名称,字体只是示例)。
  • 字体标记放入初始安装标记预取资源标记部分

  • 签名和功能中添加字体功能,并在其中的所有框中打勾

  • 在注册字体之前实现捆绑资源访问请求

像这样:

func registerFont() {
    var cfBundle: CFBundle?
    var resourceRequest: NSBundleResourceRequest?
    if let bundle = Bundle(for: type(of: self)) {
        resourceRequest = NSBundleResourceRequest(tags: Set(arrayLiteral: "fonts"), bundle: bundle)
        cfBundle = CFBundleCreate(kCFAllocatorDefault, bundle.bundleURL as CFURL)
    }
    resourceRequest?.beginAccessingResources() { error in
        if let error = error {
            print(error)
        } else {
            CTFontManagerRegisterFontsWithAssetNames(["Kanit-Regular"] as CFArray, cfBundle, .persistent, true) { (errors, done) -> Bool in
                print(errors)
                return done
            }
        }
    }
}

结果

当作用域作为.persistent.user传递时,在初始调用CTFontManagerRegisterFontsWithAssetNames函数时,将要求用户将字体安装到系统中,这不是我真正需要的。如果范围是.process.none,则返回与问题末尾提供的相同的errors输出。

虽然这个函数不符合我的需要,但我至少验证了它是工作的。也许有人会觉得有用。