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];
}
}
复制代码