简体   繁体   English

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

[英]What's the definition of Font Asset in the Asset Catalog?

Starting from iOS 13, CTFontManager has the following function:从iOS 13开始, CTFontManager有如下function:

@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)?)

However, Asset Catalog does not have any way to add "Font Assets".但是,资产目录没有任何方法可以添加“字体资产”。

What I've tried:我试过的:

  • took font KanitRegular.ttf (PostScript name is Kanit-Regular ) here .这里取字体KanitRegular.ttf (PostScript 名称是Kanit-Regular )。
  • created Data Asset named Kanit-Regular in the asset catalog.在资产目录中创建了名为Kanit-Regular的数据资产。
  • Renamed font file to Kanit-Regular.ttf and put it into the data asset.将字体文件重命名为Kanit-Regular.ttf并将其放入数据资产中。

Data Asset's Contents.json now looks like this:数据资产的Contents.json现在看起来像这样:

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

like this:像这样:

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

After this, getting errors printed:在此之后,打印errors

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

Is there any way to make it work?有什么办法让它工作吗?

Got it working by making the following:通过执行以下操作使其工作:

  • Tag the Kanit-Regular data asset with fonts On-Demand Resource Tag (tag name can be the name of your preference, fonts is just the example).使用fonts按需资源标签标记Kanit-Regular数据资产(标签名称可以是您的偏好名称, fonts只是示例)。
  • Put fonts tag into Initial Install Tags Prefetched Resource Tags sectionfonts标签放入Initial Install Tags Prefetched Resource Tags 部分

初始安装标签资源标签部分

  • Add Fonts Capability in Signing & Capabilities and tick all boxes in itSigning & Capabilities中添加Fonts Capability 并勾选其中的所有框

在此处输入图像描述

  • Implement bundle resource access request before registering fonts在注册fonts之前实现bundle资源访问请求

like this:像这样:

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

Outcome结果

When scope is passed as .persistent or .user , on initial call of CTFontManagerRegisterFontsWithAssetNames function the user will be asked to install fonts into the system, which is not what I really need.当scope被以.persistent.user的方式传递,以CTFONTMANAGERREGISTER CTFontManagerRegisterFontsWithAssetNames 0140年8月8日。 In case the scope is .process or .none , the same errors output is returned as provided at the end of the question.如果 scope 是.process.none ,则返回问题末尾提供的相同errors output 。

Although this function does not fit my needs, I at least validated that it is working.虽然这个 function 不符合我的需要,但我至少验证了它正在工作。 Maybe someone will find it useful.也许有人会发现它很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM