项目中如果只是使用几种固定的字体,可以本地添加自定义字体,可以参考iOS加入自定义字体库 这篇文章详细的说明如何在本地添加自定义字体
如果本地添加的几种字体难以满足需求,这时候就会使用从服务器动态下发字体的方式来实现,这时候就需要动态的向字体库中注册自定义字体,然后再调用[UIFont fontWithName: size:]
方法设置字体
先说下思路:
- 下载字体到APP的沙盒中,并获取到ttf文件路径
- 判断路径是否存在且有效
- 使用文件路径注册自定义字体
- 返回字体名称
- 调用
[UIFont fontWithName: size:]
方法设置字体
思路有了,剩下的就是实现
在实现之前,还需要对功能进行设计,比如怎么封装才能让这个功能简单易用?又要对外暴露哪些接口?效率等都是需要我们考虑的
在项目中,这个下载应该分属于下载模块,对于我们封装注册字体是不需要管的,同时,项目中注册的字体可能有很多,这个根据需求来定,所以我们可以使用单例实现这个功能。
记住我们的目标:给我一个字体路径,我就返回给你一个字体名称
1. 设计对外提供的接口
为了调用的方便性,我们可以对外暴露一个类方法供使用者调用
+ (NSString *)registerFontWithPath:(NSString *)path;
2. 参数合法性校验
在实现内部,我们需要判断参数的合法性
BOOL isDir;
BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:fontPath isDirectory:&isDir];
// 路径是否存在,且路径非目录
if (fontPath.length <= 0 || !isExist || (isExist && isDir)) {
return nil;
}
3. 注册字体并返回
NSURL *fontUrl = [NSURL fileURLWithPath:fontPath];
CGDataProviderRef fontDataProvider = CGDataProviderCreateWithURL((__bridge CFURLRef)fontUrl);
CGFontRef fontRef = CGFontCreateWithDataProvider(fontDataProvider);
CGDataProviderRelease(fontDataProvider);
CTFontManagerRegisterGraphicsFont(fontRef, NULL);
fontName = CFBridgingRelease(CGFontCopyPostScriptName(fontRef));
CGFontRelease(fontRef);
return fontName;
到这里,动态注册字体的介绍已经结束。
这样的设计虽然可以,但是为了app的性能,在这个单例里面还可以> 再加入字体缓存,当同一个字体路径多次请求的时候,只需要先查找> 缓存中是否有该字体,有的话直接从缓存中获取即可,这样可以避免> 重复的注册字体浪费资源。
参照iOS方法查找