如何在iOS Widgets中使用本地目录中的动态字体?

问题描述 投票:0回答:1

我目前正在开发一个 iOS 应用程序,我在主应用程序中使用 CoreText 从本地目录注册了自定义字体。现在,我想在小部件扩展中使用这些相同的自定义字体,但我不确定是否需要为小部件再次注册它们或者它们是否可以重复使用。

这是我当前的

FontManager
类的简化版本,它从应用程序中的本地目录加载和注册字体:

import Foundation
import CoreText
import CoreGraphics
import os.log

final class FontManager {
    static let shared = FontManager()
    private var registeredFonts: Set<String> = []
    private let logger = Logger(subsystem: "com.yourapp.FontManager", category: "FontManager")
    
    private init() {
        preloadRegisteredFonts()
    }

    func loadFont(from url: URL) -> Result<String, FontLoadingError> {
        guard url.isFileURL else {
            logger.error("Invalid local URL: \(url.absoluteString)")
            return .failure(.invalidLocalURL)
        }

        do {
            let fontData = try Data(contentsOf: url)
            if let postScriptName = registerFont(with: fontData) {
                return .success(postScriptName)
            } else {
                return .failure(.fontRegistrationFailed)
            }
        } catch {
            logger.error("Failed to read font data: \(error.localizedDescription)")
            return .failure(.dataReadFailed)
        }
    }

    private func registerFont(with fontData: Data) -> String? {
        guard let dataProvider = CGDataProvider(data: fontData as CFData),
              let cgFont = CGFont(dataProvider),
              let postScriptName = cgFont.postScriptName as String? else {
            logger.error("Failed to create CGFont")
            return nil
        }

        if registeredFonts.contains(postScriptName) {
            logger.info("Font already registered: \(postScriptName)")
            return postScriptName
        }

        var error: Unmanaged<CFError>?
        if CTFontManagerRegisterGraphicsFont(cgFont, &error) {
            registeredFonts.insert(postScriptName)
            logger.info("Successfully registered font: \(postScriptName)")
            return postScriptName
        } else {
            logger.error("Failed to register font: \(postScriptName)")
            return nil
        }
    }

    private func preloadRegisteredFonts() {
        if let availableFonts = CTFontManagerCopyAvailablePostScriptNames() as? [String] {
            registeredFonts = Set(availableFonts)
        }
    }
}

我的问题是:

  1. 我需要为小部件单独注册字体吗?或者我可以重复使用在主应用程序中注册的字体吗?
  2. 如果我还需要为小部件注册字体,我应该在小部件的生命周期中的哪里处理这个问题?
  3. 在小部件中使用位于应用程序本地目录中的自定义字体时是否有任何具体注意事项或限制?

任何在小部件中处理自定义字体的指导或最佳实践将不胜感激!

我希望在主应用程序中注册的字体能够自动在小部件中可用,而无需再次注册。如果这是不可能的,我希望小部件生命周期中有一个方法或位置来动态注册这些字体。

我正在寻找在小部件扩展中处理本地自定义字体的最有效方法。

ios swift swiftui widget
1个回答
0
投票

我不像你那样使用 FontManager,但我在小部件目标中使用自定义字体的方法是: 我检查了小部件字体文件的目标成员资格,并将我使用的字体文件添加到 Info.plist 文件(Widget Plist)中。为了方便起见,我还创建了一个字体扩展(内部小部件目标)。希望这个答案。

xcode custom font files

xcode custom font info.plist configurations

    extension Font {
    
    static func Comforta400(ofSize size: CGFloat) -> Font {
        return Font.custom("Comfortaa-Regular", size: size)
    }
    
    static func Comforta700(ofSize size: CGFloat) -> Font {
        return Font.custom("Comfortaa-Bold", size: size)
    }
 
}

Text("widget_qr").font(.Comforta400(ofSize: 8))
© www.soinside.com 2019 - 2024. All rights reserved.