如何使用Swift从URL下载.ttf字体文件并在App中使用
iOS 实现从URL下载TTF字体并动态使用的方案
实现步骤
1. 下载字体文件到本地沙盒
使用系统内置URLSession完成下载,可将文件存在沙盒Cache或Documents目录避免重复下载:
func downloadFont(from url: URL, completion: @escaping (URL?, Error?) -> Void) { let task = URLSession.shared.downloadTask(with: url) { tempLocalUrl, response, error in guard let tempLocalUrl = tempLocalUrl, error == nil else { completion(nil, error) return } // 移动到持久化存储目录 let cacheDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0] let savedUrl = cacheDir.appendingPathComponent(url.lastPathComponent) do { if FileManager.default.fileExists(atPath: savedUrl.path) { try FileManager.default.removeItem(at: savedUrl) } try FileManager.default.moveItem(at: tempLocalUrl, to: savedUrl) completion(savedUrl, nil) } catch { completion(nil, error) } } task.resume() }
2. 动态注册字体到当前App进程
使用CoreText框架内置的CTFontManagerRegisterFontsForURL方法完成注册,注册成功后即可和内置字体一样使用:
import CoreText func registerFont(from fileUrl: URL) -> Bool { guard FileManager.default.fileExists(atPath: fileUrl.path) else { return false } var error: Unmanaged<CFError>? // .process参数表示仅当前App进程可用,无需系统级权限 let registerSuccess = CTFontManagerRegisterFontsForURL(fileUrl as CFURL, .process, &error) if let error = error?.takeRetainedValue() { print("字体注册失败: \(error.localizedDescription)") } return registerSuccess }
提示:同名字体重复注册会返回失败,可提前通过
CTFontManagerCopyAvailablePostScriptNames检查字体是否已注册,减少不必要操作。
3. 读取字体名称并使用
字体的文件名和实际可用的PostScript名称可能不一致,需要先读取字体的真实名称再初始化UIFont:
// 从本地字体文件读取PostScript名称 func getFontPostScriptName(from fileUrl: URL) -> String? { guard let fontData = try? Data(contentsOf: fileUrl), let dataProvider = CGDataProvider(data: fontData as CFData), let cgFont = CGFont(dataProvider) else { return nil } return cgFont.postScriptName as String? } // 使用示例 if let fontName = getFontPostScriptName(from: savedFontUrl), let customFont = UIFont(name: fontName, size: 16) { // 赋值给需要自定义字体的控件 targetLabel.font = customFont }
注意事项
- 动态注册的字体仅在当前App进程内有效,App重启后需要重新注册,无需重复下载已存储在沙盒的字体文件
- 无需在Info.plist的
UIAppFonts项中配置动态下载的字体,该配置仅对打包内置到App的字体生效 - 支持TTF、OTF格式的字体,注册失败优先检查字体文件是否损坏、是否有合法使用权
- Objective-C实现逻辑完全一致,对应API为
NSURLSession、CTFontManagerRegisterFontsForURL,无系统版本兼容问题,支持iOS 12及以上所有版本
内容的提问来源于stack exchange,提问作者iosDevSan
相关产品推荐
相关产品推荐

