如何在macOS中限制NSFontPanel显示的可用字体范围
限制macOS NSFontPanel仅显示指定字体集合
要解决NSFontPanel仍显示全部系统字体的问题,核心是利用NSFontCollection定义允许的字体范围——新版macOS中,NSFontPanel的字体列表优先依赖自身配置的collection,而非单纯重写NSFontManager的属性。
解决方案步骤
1. 创建自定义字体集合
将目标字体名称转换为NSFontDescriptor数组,生成专属的NSFontCollection:
extension NSFontCollection { static var appAllowedFonts: NSFontCollection { // 你的目标字体名称列表 let allowedFontNames = ["Anton-Regular","EBGaramond-Bold","EBGaramond-BoldItalic","EBGaramond-Italic","EBGaramond-Regular","Jost-Bold","Jost-BoldItalic","Jost-Italic","Jost-Regular","Kameron-Bold", "Kameron-Regular","Licorice-Regular","OpenSans-Bold","OpenSans-BoldItalic","OpenSans-Italic","OpenSans-Regular","Roboto-Regular","Tinos-Bold","Tinos-Bolditalic","Tinos-Italic","Tinos-Regular","WaitingfortheSunrise-Regular"] // 转换为字体描述符(自动过滤无效字体) let fontDescriptors = allowedFontNames.compactMap { NSFontDescriptor(fontName: $0, size: 0) } return NSFontCollection(fontDescriptors: fontDescriptors) } }
2. 配置NSFontPanel使用自定义集合
在应用启动时(比如AppDelegate的applicationDidFinishLaunching方法),替换NSFontPanel的默认集合:
func applicationDidFinishLaunching(_ aNotification: Notification) { let fontPanel = NSFontPanel.shared // 设置自定义集合,移除原有所有字体 fontPanel.setCollection(.appAllowedFonts, options: [.removeExisting]) // 刷新字体面板 fontPanel.reloadDefaultFontFamilies() }
3. 简化自定义FontManager(可选)
如果仍需要处理字体选择的有效性校验,可保留fontManager(_:willIncludeFont:)方法,其他重载属性可移除(集合已过滤显示列表):
class FontManager: NSFontManager { static let allowedFonts: [String] = ["Anton-Regular", /*... 你的字体列表 ...*/] override required init() { super.init() } public override func fontManager(_ sender: Any, willIncludeFont fontName: String) -> Bool { return Self.allowedFonts.contains(fontName) } }
启动时记得注册FontManager:
NSFontManager.setFontManagerFactory(FontManager.self)
为什么之前的方法无效?
旧版macOS中重写availableFonts等属性可过滤字体,但新版系统中NSFontPanel的显示逻辑已切换为优先使用自身的NSFontCollection配置,单纯重载NSFontManager的属性不再能影响面板显示的字体列表。
内容的提问来源于stack exchange,提问作者vajra
相关产品推荐
相关产品推荐

