在iOS开发中使⽤⾃定义字体
在iOS的项⽬开发中经常遇到需要使⽤⼀些⾃定义的字体⽂件,⽐如仿宋_GB2312、⽅正⼩标宋_GBK等。之前我们为了使⽤这些⾃定义的字体,
在应⽤的资源包中放⼊这些字体⽂件。因为字体⽂件通常⽐较⼤,有的⼀个字库就达到10M以上(拿⽅正⼩标宋_GBK这个字库来说就有13M之
多),这样打包后的ipa⽂件的体积就可能会变得很⼤,对于只有个别的模块需要特殊的字体样式的应⽤来说很不划算,那么在iOS6.0以后苹果就
开放了动态加载字体的权限。下⾯就iOS中使⽤字体的这两种⽅式进⾏介绍。
###使⽤静态字体
1、将字体⽂件拷贝到项⽬⼯程中,在⽂件中添加Fontsprovidedbyapplication的配置项,其中每⼀个Item对应的是字体⽂件的名
称,如。
2、使⽤时直接按照如下⽅式即可:
_=[UIFontfontWithName:@"DS-Digital"size:40];
效果如下:
3、其他说明:
+(UIFont*)fontWithName:(NSString*)fontNamesize:(CGFloat)fontSize;这个⽅法中需要指定的fontName不是前⾯设置的字体⽂件的⽂
件名,⽽应该是字体的名称,如何获取字体的名称可以通过如下⽅式:
(1)打印出当前所有可⽤的字体,查找对应的字体名称
-(void)printAllFonts
{
NSArray*fontFamilies=[UIFontfamilyNames];
for(NSString*fontFamilyinfontFamilies)
{
NSArray*fontNames=[UIFontfontNamesForFamilyName:fontFamily];
NSLog(@"%@:%@",fontFamily,fontNames);
}
}
(2)通过Mac⾃带的字体册查看字体的名称
直接双击字体即可打开字体册,如果系统没有安装该字体按照要求安装即可,然后可以在字体的详细信息中找到对应的字体的名称:
###使⽤动态字体
1、动态下载⾃定义的字体
在⽹易新闻iOS客户端中可以使⽤⾃定义的字体,对于未下载的字体可先下载然后安装下次就能⾃动设置为该字体,效果如下:
下⾯就该功能简单介绍实现的步骤
#(1)下载指定的字体⽂件到本地
第⼀次进⼊该页⾯会⾃动到服务器上获取可使⽤的字体的列表,⽰例如下:
[
{
"fontTitle":"华康圆体",
"regularName":"DFYuanW3-GB",
"boldName":"DFYuanW5-GB",
"author":"华康科技",
"date":"2012-10-11",
"fileUrl":"xxxx/font/dfgb_",
"fileSize":"3.3MB",
"previewUrl":"yyyy/font/ios_"
}
]
上⾯的内容指明了字体的名称,下载地址等信息,从上⾯的内容可以看出下载回来的字体⽂件是⼀个zip压缩包,再使⽤前还需要进⾏解压处理。
##1)下载字体⽂件
-(NSString*)downloadZipFile:(NSString*)fileUrltoPath:(NSString*)path
{
NSError*error=nil;
NSURL*url=[NSURLURLWithString:fileUrl];
NSString*fileName=[urllastPathComponent];
NSData*data=[NSDatadataWithContentsOfURL:urloptions:0error:&error];
if(!error)
{
NSString*zipPath=[pathstringByAppendingPathComponent:fileName];
[datawriteToFile:zipPathoptions:0error:&error];
if(!error)
{
returnzipPath;
}
}
returnnil;
}
##2)解压zip压缩包
iOS中解压zip压缩⽂件⾮常⽅便,使⽤ZipArchive这个开源项⽬按照如下的⽅式即可快速解压zip⽂件。
-(NSString*)expandZipFile:(NSString*)srctoPath:(NSString*)desc
{
ZipArchive*za=[[ZipArchivealloc]init];
if([zaUnzipOpenFile:src])
{
BOOLret=[zaUnzipFileTo:descoverWrite:YES];//解压⽂件
if(ret)
{
NSString*zipName=[srclastPathComponent];//获取zip⽂件的⽂件名
[[NSFileManagerdefaultManager]removeItemAtPath:zipPatherror:nil];//删除zip压缩包
zipName=[zipNamesubstringToIndex:[zipNamerangeOfString:@".zip"].location];//获取解压到的⽂件夹
return[adPathstringByAppendingPathComponent:zipName];
}
}
returnnil;
}
#(2)注册指定路径下的字体⽂件
下载回来的字体⽂件如果不做处理是不能直接使⽤的,使⽤前需要先注册然后才能使⽤,注册⽅式如下:
-(void)registerFont:(NSString*)fontPath
{
NSData*dynamicFontData=[NSDatadataWithContentsOfFile:fontPath];
if(!dynamicFontData)
{
return;
}
CFErrorReferror;
CGDataProviderRefproviderRef=CGDataProviderCreateWithCFData((__bridgeCFDataRef)dynamicFontData);
CGFontReffont=CGFontCreateWithDataProvider(providerRef);
if(!CTFontManagerRegisterGraphicsFont(font,&error))
{
//注册失败
CFStringReferrorDescription=CFErrorCopyDescription(error);
NSLog(@"Failedtoloadfont:%@",errorDescription);
CFRelea(errorDescription);
}
CFRelea(font);
CFRelea(providerRef);
}
需要先引⼊#import
#(3)判断字体是否加载
在使⽤字体⽂件前最好是先判断字体是否已经被加载过了,判断⽅式如下:
-(BOOL)isFontDownloaded:(NSString*)fontName
{
UIFont*aFont=[UIFontfontWithName:fontNamesize:12.0];
BOOLisDownloaded=(aFont&&([mecompare:fontName]==NSOrderedSame||[Name
compare:fontName]==NSOrderedSame));
returnisDownloaded;
}
#(4)其他说明
经测试注册过的字体在应⽤关闭后下次开启应⽤,判断字体是否加载时返回为NO,为了保证正常使⽤需要每次启动应⽤的时候先遍历⼀遍字体⽂
件夹将⾥⾯的字体⽂件都再次注册⼀遍即可。参考代码如下:
//注册fonts⽬录下⾯的所有字体⽂件
NSArray*ary=[[NSFileManagerdefaultManager]contentsOfDirectoryAtPath:adPatherror:nil];
for(NSString*p1inary)
{
NSString*t1=[adPathstringByAppendingPathComponent:p1];
NSArray*ary1=[[NSFileManagerdefaultManager]contentsOfDirectoryAtPath:t1error:nil];
for(NSString*p1inary1)
{
NSString*t2=[t1stringByAppendingPathComponent:p1];
if([t2rangeOfString:@".ttf"].location!=NSNotFound)
{
[lfregisterFont:t2];
}
}
}
2、动态下载苹果提供的字体
⼤多数的中⽂字体是有版权的,在应⽤中加⼊特殊中⽂字体还需要处理相应的版权问题。从iOS6开始,苹果就⽀持动态下载中⽂字体到系统中。
(1)苹果⽀持下载的字体列表
(2)官⽅提供的⽰例代码
1)判断字体是否已经被下载过
UIFont*aFont=[UIFontfontWithName:fontNamesize:12.];
if(aFont&&([mecompare:fontName]==NSOrderedSame||[Namecompare:fontName]==
NSOrderedSame)){
//字体已经被加载过,可以直接使⽤
return;
}
2)下载字体
根据字体的PostScript名称构建下载字体所需的参数:
//使⽤字体的PostScript名称构建⼀个字典
NSMutableDictionary*attrs=[NSMutableDictionarydictionaryWithObjectsAndKeys:fontName,kCTFontNameAttribute,nil];
//根据上⾯的字典创建⼀个字体描述对象
CTFontDescriptorRefdesc=CTFontDescriptorCreateWithAttributes((__bridgeCFDictionaryRef)attrs);
//将字体描述对象放到⼀个数组中
NSMutableArray*descs=[NSMutableArrayarrayWithCapacity:0];
[descsaddObject:(__bridgeid)desc];
CFRelea(desc);
下载字体⽂件:
_blockBOOLerrorDuringDownload=NO;
CTFontDescriptorMatchFontDescriptorsWithProgressHandler((__bridgeCFArrayRef)descs,NULL,
^(CTFontDescriptorMatchingStatestate,CFDictionaryRefprogressParameter){
//下载的进度
doubleprogressValue=[[(__bridgeNSDictionary*)progressParameterobjectForKey:
(id)kCTFontDescriptorMatchingPercentage]doubleValue];
if(state==kCTFontDescriptorMatchingDidBegin){
dispatch_async(dispatch_get_main_queue(),^{
//开始匹配
NSLog(@"BeginMatching");
});
}elif(state==kCTFontDescriptorMatchingDidFinish){
dispatch_async(dispatch_get_main_queue(),^{
if(!errorDuringDownload){
//字体下载完成
NSLog(@"%@downloaded",fontName);
//TODO:在此修改UI控件的字体样式
}
});
}elif(state==kCTFontDescriptorMatchingWillBeginDownloading){
//开始下载
NSLog(@"BeginDownloading");
dispatch_async(dispatch_get_main_queue(),^{
//TODO:在此显⽰下载进度提⽰
});
}elif(state==kCTFontDescriptorMatchingDidFinishDownloading){
//下载完成
NSLog(@"Finishdownloading");
dispatch_async(dispatch_get_main_queue(),^{
//TODO:在此修改UI控件的字体样式,隐藏下载进度提⽰
});
}elif(state==kCTFontDescriptorMatchingDownloading){
//正在下载
NSLog(@"Downloading%.0f%%complete",progressValue);
dispatch_async(dispatch_get_main_queue(),^{
//TODO:在此修改下载进度条的数值
});
}elif(state==kCTFontDescriptorMatchingDidFailWithError){
//下载遇到错误,获取错误信息
NSError*error=[(__bridgeNSDictionary*)progressParameterobjectForKey:(id)kCTFontDescriptorMatchingError];
NSLog(@"%@",[errorlocalizedDescription]);
//设置下载错误标志
errorDuringDownload=YES;
}
return(bool)YES;
});
(3)说明
1)使⽤动态下载中⽂字体的API可以动态地向iOS系统中添加字体⽂件,这些字体⽂件都是下载到系统的⽬录中(⽬录
是/private/var/mobile/Library/Asts/com_apple_MobileAst_Font/),所以并不会造成应⽤体积的增加,⽽且可以在多个应⽤中共
享。
2)如何获取字体的PostScript和FontName?可以通过Mac系统⾃带的字体册来查看。具体请参考前⾯的步骤。
###参考资料
1、《动态下载苹果提供的多种中⽂字体》
2、《字体加载三种⽅式》
3、《在iOS程序中使⽤⾃定义字体》
本文发布于:2022-12-26 15:00:58,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/34343.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |