Created by shuimu 2020/05/25bash
提交到應用商店的容許在操做系統中提供系統範圍內可用字體的應用程序。app
要建立一個字體提供app,須要知足兩個條件:async
Fonts
相關的 entitlement
。在Capabilities
中找到並添加 Fonts
ide
Fonts
包含兩個選項: post
Install Fonts:安裝字體。字體
使app可以在系統範圍內提供字體ui
Use Installed Fonts:使用已安裝的字體。url
默認狀況下,應用程序沒法訪問用戶安裝的字體。應用程序須要選擇這個功能,才能看到這些字體。spa
CoreText/CTFontManager.h
,引入了相關的APIs:操作系統
CTFontManagerRegisterFontURLs
使用指向字體文件的FontURLs
CTFontManagerRegisterFontDescriptors
經過使用字體描述符註冊字體
CTFontManagerRegisterFontsWithAssetNames
註冊存在於應用程序中的字體資源
CTFontManagerCopyRegisteredDescriptors
字體提供app用於訪問已註冊的字體
CTFontManagerRequestFonts
首先,應用程序應該提供一個有意義的UI,用戶能夠在其中瀏覽字體、安裝和刪除字體。
這是必要的,由於在iOS中,咱們沒有一個應用程序能夠像在macOS中那樣在操做系統中安裝字體。
此外,應用程序應該響應系統字體更改通知。
緣由是:用戶可以在
設置
中刪除字體,且應用應該注意到這一點並及時更新它的UI。
最後,若是你是一個字體提供程序,它計劃提供一組很大的字體給用戶,一個很大的字體庫。
咱們強烈建議您使用按需資源並將字體打包到資產目錄中。
這是一種更有效的交付用戶所需字體的方式,由於用戶將只下載他們實際將要使用的字體。而不是下載一個巨大的字體庫。
添加觀察者,以便響應系統字體變動通知。
e.g.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fontsChangedNotification:) name:(__bridge NSString *)kCTFontManagerRegisteredFontsChangedNotification object:nil];
複製代碼
- (void)fontsChangedNotification:(id)noti {
// 處理字體更新 ...
[FontProvider updateRegisterdFonts];
dispatch_async(dispatch_get_main_queue(), ^{
// 更新相關UI ...
});
}
複製代碼
Register from fontURLs.
- (void)registerFontWithFontURL:(NSURL *)fontURL {
NSURL *urls[] = {fontURL};
CFArrayRef fontURLs = CFArrayCreate(kCFAllocatorDefault, (void *)urls, (CFIndex)1, NULL);
CTFontManagerRegisterFontURLs(fontURLs, kCTFontManagerScopePersistent, true, ^bool(CFArrayRef _Nonnull errors, bool done) {
if (CFArrayGetCount(errors) > 0) {
// regist failed
CFErrorRef cfError = (CFErrorRef)CFArrayGetValueAtIndex(errors, 0);
NSError *error = (__bridge_transfer NSError *)cfError;
NSLog(@"Regist Font Failed: %@", [error localizedDescription]);
return false;
}
return true;
});
}
複製代碼
Register from an asset catalog.
- (void)registerFontWithFontAssetName:(NSString *)fontAssetName {
NSString *values[] = {fontAssetName};
CFArrayRef arrRef = CFArrayCreate(kCFAllocatorDefault, (void *)values, (CFIndex)1, NULL);
CTFontManagerRegisterFontsWithAssetNames(arrRef, nil, kCTFontManagerScopePersistent, true, ^bool(CFArrayRef _Nonnull errors, bool done) {
if (CFArrayGetCount(errors) > 0) {
// regist failed
CFErrorRef cfError = (CFErrorRef)CFArrayGetValueAtIndex(errors, 0);
NSError *error = (__bridge_transfer NSError *)cfError;
NSLog(@"Regist Font Failed: %@", [error localizedDescription]);
return false;
}
return true;
});
}
複製代碼
註冊方法中部分參數說明:
kCTFontManagerScopePersistent
以便其餘app可使用該字體CTFontManagerRequestFonts
被發現。通常選擇true。Unregister by FontURLs.
- (void)unregisterFontWithFontURL:(NSURL *)fontURL {
NSURL *urls[] = {fontURL};
CFArrayRef fontURLs = CFArrayCreate(kCFAllocatorDefault, (void *)urls, (CFIndex)1, NULL);
CTFontManagerUnregisterFontURLs(fontURLs, kCTFontManagerScopePersistent, ^bool(CFArrayRef _Nonnull errors, bool done) {
if (CFArrayGetCount(errors) > 0) {
// regist failed
CFErrorRef cfError = (CFErrorRef)CFArrayGetValueAtIndex(errors, 0);
NSError *error = (__bridge_transfer NSError *)cfError;
NSLog(@"Regist Font Failed: %@", [error localizedDescription]);
return false;
}
return true;
});
}
複製代碼
Unregister by Font Descriptor.
- (void)unregisterFontWithFontDescriptor:(UIFontDescriptor *)fontDescriptor {
CTFontDescriptorRef fontDescriptors[] = {(__bridge CTFontDescriptorRef)fontDescriptor};
CTFontManagerUnregisterFontDescriptors(CFArrayCreate(kCFAllocatorDefault, (void *)fontDescriptors, (CFIndex)1, NULL), kCTFontManagerScopePersistent, ^bool(CFArrayRef _Nonnull errors, bool done) {
if (CFArrayGetCount(errors) > 0) {
// regist failed
CFErrorRef cfError = (CFErrorRef)CFArrayGetValueAtIndex(errors, 0);
NSError *error = (__bridge_transfer NSError *)cfError;
NSLog(@"Unregist Font Failed: %@", [error localizedDescription]);
return false;
}
return true;
});
}
複製代碼
CTFontManagerCopyRegisteredFontDescriptors
僅可獲取字體提供應用本身註冊的字體
- (void)getRegisteredFonts {
[FontProvider.registeredFonts removeAllObjects];
CFArrayRef registerdDescriptors = CTFontManagerCopyRegisteredFontDescriptors(kCTFontManagerScopePersistent, true);
for (CFIndex i = 0; i < CFArrayGetCount(registerdDescriptors); i ++) {
CTFontDescriptorRef fontDescriptorRef = CFArrayGetValueAtIndex(registerdDescriptors, i);
UIFontDescriptor *fontDescriptor = (__bridge_transfer UIFontDescriptor *)fontDescriptorRef;
// save registered fonts ...
[FontProvider.registeredFonts addObject:fontDescriptor];
}
}
複製代碼