美文网首页综合
iOS 动态加载字体

iOS 动态加载字体

作者: MccReeee | 来源:发表于2018-12-06 14:21 被阅读17次
  • iOS动态加载字体有两种方案

1.加载系统自带字体, 虽然叫系统自带字体, 但还是需要通过网络下载. 系统自带字体下载是由系统完成, 也不会存在app沙盒中. 一次下载永久存储, 除非手机恢复出厂. 但是app使用前需要注册下字体.

具体看代码,注意下载的网络请求会由系统发起,你不需要通过AFNetworking去管理.

+(void)vsc_fontWithPostScriptName:(NSString *)fontName
                          chsName:(NSString *)chsName
                         fontSize:(CGFloat)fontSize
                         progress:(void (^)(CGFloat progress))progress
                         complete:(void (^)(UIFont *font))complete
                          failure:(void (^)(NSError *error))failure{
    if (!complete) {
        return;
    }
    UIFont *existFont = [self existFontWithPostScriptName:fontName fontSize:fontSize];
    if (existFont) {
        complete(existFont);
        return;
    }
    //用字体的PostScript名字创建一个Dictionary
    NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithObjectsAndKeys:fontName, kCTFontNameAttribute, nil];
    
    // 创建一个字体描述对象CTFontDescriptorRef
    CTFontDescriptorRef desc = CTFontDescriptorCreateWithAttributes((__bridge CFDictionaryRef)attrs);
    
    //将字体描述对象放到一个NSMutableArray中
    NSMutableArray *descs = [NSMutableArray arrayWithCapacity:0];
    [descs addObject:(__bridge id)desc];
    CFRelease(desc);
    
    __block BOOL errorDuringDownload = NO;
    //开始对字体进行下载
    CTFontDescriptorMatchFontDescriptorsWithProgressHandler( (__bridge CFArrayRef)descs, NULL,  ^(CTFontDescriptorMatchingState state, CFDictionaryRef progressParameter) {
        CGFloat progressValue = [[(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingPercentage] floatValue];
        
        switch (state) {
            case kCTFontDescriptorMatchingDidBegin:{//字体已经匹配
                
            }
                break;
            case kCTFontDescriptorMatchingDidFinish:{//字体下载完成
                if (!errorDuringDownload) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        UIFont *font = [UIFont fontWithName:fontName size:fontSize];
                        complete(font);
                    });
                }
            }
                break;
            case kCTFontDescriptorMatchingWillBeginDownloading:{//字体开始下载
//                [self downloadAlertWithPostScriptName:fontName chsName:chsName];
                if (needToReask) {
                    needToReask = NO;
                    errorDuringDownload = YES;
                    return (bool)NO;
                }
            }
                break;
            case kCTFontDescriptorMatchingDidFinishDownloading:{//字体下载完成
                dispatch_async(dispatch_get_main_queue(), ^{
                    UIFont *font = [UIFont fontWithName:fontName size:fontSize];
                    complete(font);
                });
            }
                break;
            case kCTFontDescriptorMatchingDownloading:{//下载进度
                if (progress) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        progress(progressValue);
                    });
                }
            }
                break;
            case kCTFontDescriptorMatchingDidFailWithError:{//下载失败
                NSError *error = [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError];
                if (!error) {
                    error = [NSError errorWithDomain:@"ERROR MESSAGE IS NOT AVAILABLE" code:102 userInfo:nil];
                }
                errorDuringDownload = YES;
                if (failure) {
                    failure(error);
                }
            }
                break;
            default:
                break;
        }
        return (bool)YES;
    });
}
  • 使用字体时和平时一样, 这里的fontName就是刚才下载的fontName
UIFont *font = [UIFont fontWithName:fontName size:18];
self.lab.font = font;
  • 那么如何查看我可以下载哪些字体,以及下载的字体具体叫什么名字呢
    其实iOS上的字体和macOS上的字体是通用的,并且字体的版权也是一致的,macOS系统上自带的字体iOS上都能用.
    所以只要查看macOS上的字体就可以了.
    打开macOS,找到系统自带的字体程序


    6C2E4A89-E2B9-4CE3-B2EC-02578E020531.jpeg

打开来后是这个样子的,左侧显示字体的名称, 右测红框中显示的就是FontName


image.png

有个注意点,就是app加载过字体后,重新启动可能发现字体没有了,其实字体不是没有,而是没有加载进app,系统虽然下载好了,但是并没有加载进来, 所以建议在AppDelegate启动后再调一次下载字体的函数,让字体从系统加载到app中.


2.方案二,app动态下载字体文件到沙盒,再从沙盒加载. 字体文件是一个后缀为ttf的文件.比如这个.

image.png

网络下载就用AFNetworking之类的框架, 我自己是用的YTKNetwork,就像下载文件到本地一样,把字体文件下载到沙盒中.

之后就是加载字体

if ([fontReq existFontName]) {
            NSLog(@"字体已存在:%@",fontReq.fontName);
            
            NSString * fontPath = [NSString stringWithFormat:@"%@/%@",Rubick_Document, fontReq.fontName];
;
            CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename([fontPath UTF8String]);
            CGFontRef customfont = CGFontCreateWithDataProvider(fontDataProvider);
            CGDataProviderRelease(fontDataProvider);
            NSString *fontName = (__bridge NSString *)CGFontCopyFullName(customfont);
            CFErrorRef error;
            CTFontManagerRegisterGraphicsFont(customfont, &error);
            if (error){
                // 为了可以重复注册
                CTFontManagerUnregisterGraphicsFont(customfont, &error);
                CTFontManagerRegisterGraphicsFont(customfont, &error);
            }
            CGFontRelease(customfont);
            UIFont *font = [UIFont fontWithName:fontName size:18];
            //给label设置字体
            self.lab.font = font;
            
            return;
        }

注意, 这里的fontName可能和你想的不太一样


image.png

END

相关文章

  • iOS 动态加载字体

    iOS动态加载字体有两种方案 1.加载系统自带字体, 虽然叫系统自带字体, 但还是需要通过网络下载. 系统自带字体...

  • iOS 动态加载字体

  • iOS动态字体加载及坑

    首先,在iOS中,使用字体文件(网络动态下载或者copy到bundle的方式)并不难,只需要在使用前动态加载就可以...

  • iOS 动态加载自定义字体

  • Flutter 动态加载字体

    如果需要从网络上下载字体并且应用 关键代码Future loadFontToApp(String pa...

  • Flutter 字体动态加载

    前言 Flutter在运行web版时,加载完成字体之后,才会展示页面,巧合的是我的字体文件是4.8M,更巧合的是,...

  • js动态加载字体

    之前做类似易企秀的项目需要动态引入字体,上代码 全部加载方式 参数说明 fontList为字体资源列表,然后在需要...

  • 移动端自适应方案

    绑定浏览器缩放和加载事件,动态修正跟字体大小

  • 多种中文字体

    功能介绍 使用动态下载中文字体的 API 可以动态地向 iOS 系统中添加字体文件,这些字体文件都是下载到系统的目...

  • iOS---10--- _read_images 浅析 类的加载

    [toc] 前言 在iOS程序中会用到很多系统的动态库,这些动态库都是动态加载的。所有iOS程序共用一套系统动态库...

网友评论

    本文标题:iOS 动态加载字体

    本文链接:https://www.haomeiwen.com/subject/khcocqtx.html