使用来自 xcfamework 的字体

Posted

技术标签:

【中文标题】使用来自 xcfamework 的字体【英文标题】:Using fonts from xcfamework 【发布时间】:2021-06-23 08:32:51 【问题描述】:

所以我有 xcframework,其中包含字体文件(来自 react-native-vector-icons)。

在测试项目 (testApp) 中,我正在导入 xcframework,我希望它从我的框架中复制资源,但不幸的是它不会复制 xcframework 中的这些字体,我必须在 Copy Bundle 中手动添加它资源。

对于最终用户,我不希望他们进入框架并手动添加。

在我的框架中,我在构建阶段拥有 Cops Pods 资源,但没有做任何事情来告诉使用该框架的项目复制这些字体(或资源)。

我需要做什么才能在项目中自行复制字体(或资源)?而不是手动操作?

【问题讨论】:

你从那个框架里得到字体文件了吗? 如果是,则可以使用filemanager 将其复制并粘贴到文件夹中,并在获取这些字体时检查 at 路径是否存在任何字体文件而不是安装它们。这可能是一个漫长的过程。 理论上可以通过文件路径获取任意文件。我已经使用这种方法从其他第三方库中获取图片。你可以试试,希望对你有帮助。 【参考方案1】:

如果您使用 Cocoapods 分发您的 xcframework,那么您可以让任何资源文件由 Cocoapods 自动复制到目标 .app 包中。

在您的 podspec 中,您定义需要复制的资源和 xcframework(以及 NO spec.sources):

spec.resources = ['Fonts/EncodeSans-ExtraBold.ttf']
spec.vendored_frameworks = 'Example.xcframework'

或者从 xcframework 内部:

spec.resources = ['Example.xcframework/<a path>/EncodeSans-ExtraBold.ttf']
spec.vendored_frameworks = 'Example.xcframework'

当您执行pod install 时,Cocoapods 将创建一个“[CP] Copy Pods Resources”阶段,该阶段将在目标应用程序中复制您在资源中定义的任何内容:

为避免冲突(用户或其他 pod 可能会复制相同的文件),最好使用 resource_bundles 而不是资源。

【讨论】:

【参考方案2】:

您需要使用字体管理器注册字体。我做了这个扩展UIFont

extension UIFont 
    private class ModuleClass 
    static func fontsURLs() -> [URL] 
        let bundle = Bundle(for: ModuleClass.self)
        let fileNames = ["Feather"]

        return fileNames.compactMap  fontName in
            bundle.url(forResource: fontName, withExtension: "ttf")
        
    
    
    /// Registers the specified graphics font with the font manager.
    /// - Parameter url: Bundle URL of the font to register
    /// - Throws: If font cannot be registered
    static func register(from url: URL) throws 
        guard let fontDataProvider = CGDataProvider(url: url as CFURL) else 
            throw FontError.dataProviderNotCreated(message: "Could not create font data provider for \(url).")
        
        
        guard let font = CGFont(fontDataProvider) else 
            throw FontError.fontNotCreated(message: "Could not create font data provider for \(url).")
        
        
        var error: Unmanaged<CFError>?
        guard CTFontManagerRegisterGraphicsFont(font, &error) else 
            throw error?.takeUnretainedValue() ?? FontError.fontNotRegistered
        
    

那么,你需要使用这个。

public extension UIFont 
/// Registers the specified graphics font with the font manager.
    /// Registered fonts participate in font descriptor matching.
    static func registerFonts() 
        let urls = fontsURLs()
        for url in urls 
            do 
                try register(from: url)
             catch 
                debugPrint(error)
            
        
    

并在您的主项目(应用程序)中注册字体

// In AppDelegate.swift
import YourModule

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
    UIFont.registerFonts()
    return true

【讨论】:

以上是关于使用来自 xcfamework 的字体的主要内容,如果未能解决你的问题,请参考以下文章

Qml 字体使用pixelSize来自适应界面

Qml 字体使用pixelSize来自适应界面

如何在 Chrome 中使用来自谷歌字体的 Roboto Light/Thin

Firefox 不呈现来自 CloudFront 的字体

显示来自 Entypo 字体的 5 位基本 unicode 字符

字体反爬,一种来自字体设计师的跨行反爬案例 | 案例 28