You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS应用如何区分系统预装字体与动态加载字体?

区分iOS系统预装字体与动态加载字体的方案

嘿,刚好做过类似的需求,给你几个实用的方法来区分系统字体和你动态加载的自定义字体,还能轻松实现表格里的勾选标记功能:

方案一:提前缓存系统字体列表(最简单直接)

因为你的自定义字体是在App启动后才下载加载的,那我们可以在自定义字体加载之前,先把系统预装的字体列表缓存下来。之后只要对比当前字体是否在缓存列表里,就能快速区分了。

实现步骤:

  1. 在App启动初期(比如AppDelegate的didFinishLaunchingWithOptions方法里)缓存系统字体:
// 可以定义全局变量或者用单例来存储这些缓存
var preloadedSystemFontFamilies: Set<String> = []
var preloadedSystemFontNames: Set<String> = []

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 缓存系统字体家族名
    preloadedSystemFontFamilies = Set(UIFont.familyNames)
    // 缓存所有系统字体的具体名称
    UIFont.familyNames.forEach { familyName in
        let fontNames = UIFont.fontNames(forFamilyName: familyName)
        preloadedSystemFontNames.formUnion(fontNames)
    }
    return true
}
  1. 判断字体是否为系统预装:
// 按字体家族名判断
func isSystemFontFamily(_ familyName: String) -> Bool {
    return preloadedSystemFontFamilies.contains(familyName)
}

// 按具体字体名判断
func isSystemFont(_ fontName: String) -> Bool {
    return preloadedSystemFontNames.contains(fontName)
}

方案二:利用CoreText的注册字体API

CoreText提供了直接获取动态注册字体的方法,我们可以通过CTFontManagerCopyRegisteredFonts筛选出所有通过CTFontManagerRegisterGraphicsFont注册的自定义字体,剩下的就是系统预装字体了。

实现代码:

import CoreText

func getDynamicallyInstalledFonts() -> Set<String> {
    var dynamicFonts = Set<String>()
    // 获取所有已注册的启用字体
    guard let registeredFontDescriptors = CTFontManagerCopyRegisteredFonts(.enabled, nil) as? [CTFontDescriptor] else {
        return dynamicFonts
    }
    
    for descriptor in registeredFontDescriptors {
        // 检查该字体是否是动态注册的(非系统预装)
        if let isDynamicallyRegistered = CTFontDescriptorCopyAttribute(descriptor, kCTFontManagerRegisteredFontAttribute) as? Bool, isDynamicallyRegistered {
            // 获取字体名称
            if let fontName = CTFontDescriptorCopyAttribute(descriptor, kCTFontNameAttribute) as? String {
                dynamicFonts.insert(fontName)
            }
        }
    }
    return dynamicFonts
}

之后你可以用这个集合来对比,不在集合里的就是系统字体。

表格单元格添加勾选标记的技巧

你需要维护一个已安装自定义字体的列表(可以存在UserDefaults或者本地数据库里),每次调用install_font函数成功后,就把对应的字体名称/家族名添加到这个列表里。

在表格的cellForRowAt方法里:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "FontCell", for: indexPath)
    let font = availableFonts[indexPath.row] // availableFonts是你的可安装字体列表
    
    // 设置字体名称等内容
    cell.textLabel?.text = font.familyName
    
    // 判断是否已安装,显示勾选标记
    let installedFonts = UserDefaults.standard.stringArray(forKey: "InstalledFonts") ?? []
    if installedFonts.contains(font.familyName) {
        cell.accessoryType = .checkmark
    } else {
        cell.accessoryType = .none
    }
    
    return cell
}

注意事项:

  • 方案一要确保缓存系统字体的代码早于自定义字体加载的代码执行,不然缓存里会包含自定义字体,导致区分失效。
  • 如果之后需要卸载自定义字体,记得同时更新已安装列表(方案一的缓存无需更新,因为它记录的是初始系统字体状态)。

内容的提问来源于stack exchange,提问作者Alexandru Vasiliu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:59:02