动态下载系统提供的多种中文字体

本文介绍如何在iOS中动态下载和使用苹果官方提供的中文字体,以节省应用体积并避免版权问题。通过特定API,字体下载后可被所有应用共享。详细步骤包括检查字体是否已下载、下载字体及处理下载进度。
摘要由CSDN通过智能技术生成

 iOS6开始,苹果开始支持动态下载官方提供的中文字体到系统中。使用苹果官方提供的中文字体,既可以避免版权问题,又可以节省应用体积。该方案适合对有较多需求的应用。


 使用动态下载中文字体的API可以动态地向iOS系统中添加字体文件,这些字体文件都是下载到系统的目录中(目录是/private/var/mobile/Library/Assets/com_apple_MobileAsset_Font/),所以并不会造成应用体积的增加。由于字体文件是iOS系统提供的,也免去了字体使用版权的问题。虽然第一次下载相关的中文字体需要一些网络开销和下载时间,但是这些字体下载后可以在所有应用间共享,所以可以预见,随着该API使用的普及,大部分应用都不需要提示用户下载字体,因为很可能这些字体在之前就被其他应用下载下来了。


 在官方文档(http://support.apple.com/kb/HT5484?viewlocale=zh_CN)中,苹果列出了提供动态下载和使用的中文字体文件列表。不过由于下载的时候需要使用的名字是PostScript名称,所以如果你真正要动态下载相应的字体的话,还需要使用Mac内自带的应用字体册Font Book)来获得相应字体的PostScript名称。


 苹果提供了动态下载代码的Demo工程(https://developer.apple.com/library/ios/samplecode/DownloadFont/Listings/DownloadFont_ViewController_m.html)。


#import "ViewController.h"

#import <CoreText/CoreText.h>


@interface ViewController ()

{

    NSString *_errorMessage;

    UILabel *_label;

}


@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    

    _label = [[UILabel alloc] initWithFrame:CGRectMake(10, 30, 300, 30)];

    _label.text = @"2016大发大发大发大发大发";

    _label.font = [UIFont systemFontOfSize:12];

    _label.backgroundColor = [UIColor yellowColor];

    [self.view addSubview:_label];

    

    NSString *fontName = @"STXingkai-SC-Light";

    if (![self isFontDownloaded:fontName]) {

        [self downloadFont:fontName];

    }

}


// 先判断该字体是否已经被下载下来

- (BOOL)isFontDownloaded:(NSString *)fontName

{

    UIFont *aFont = [UIFont fontWithName:fontName size:12.0];

    if (aFont && ([aFont.fontName compare:fontName] == NSOrderedSame || [aFont.familyName compare:fontName] == NSOrderedSame)) {

        return YES;

    } else {

        return NO;

    }

}


// 如果该字体已经下载过了,则可以直接使用。否则我们需要先准备下载字体API需要的一些参数

- (void)downloadFont:(NSString *)fontName

{

    // 用字体的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);

    

    // 准备好上面的descs变量后,就可以进行字体的下载了

    __block BOOL errorDuringDownload = NO;

    

    CTFontDescriptorMatchFontDescriptorsWithProgressHandler((__bridge CFArrayRef)descs, NULL, ^bool(CTFontDescriptorMatchingState state, CFDictionaryRef  _Nonnull progressParameter) {

        

        double progressValue = [[(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingPercentage] doubleValue];

        

        if (state == kCTFontDescriptorMatchingDidBegin) {

            NSLog(@"字体已经匹配");

        } else if (state == kCTFontDescriptorMatchingDidFinish) {

            if (!errorDuringDownload) {

                NSLog(@"字体%@ 下载完成", fontName);

                dispatch_async(dispatch_get_main_queue(), ^{

                    // 可以在这里修改UI控件的字体

                    _label.font = [UIFont fontWithName:fontName size:12];

                });

            }

        } else if (state == kCTFontDescriptorMatchingWillBeginDownloading) {

            NSLog(@"字体开始下载");

        } else if (state == kCTFontDescriptorMatchingDidFinishDownloading) {

            NSLog(@"字体下载完成");

        } else if (state == kCTFontDescriptorMatchingDownloading) {

            NSLog(@"下载进度 %.0f%%", progressValue);

        } else if (state == kCTFontDescriptorMatchingDidFailWithError) {

            NSError *error = [(__bridge NSDictionary *)progressParameter objectForKey:(id)kCTFontDescriptorMatchingError];

            if (error != nil) {

                _errorMessage = [error description];

            } else {

                _errorMessage = @"ERROR MESSAGE IS NOT AVAILABLE!";

            }

            

            // 设置标志

            errorDuringDownload = YES;

            NSLog(@"下载错误: %@", _errorMessage);

        }

        

        return YES;

    });

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值