前段时间在开发中遇到一个小问题需要自定义app的字体。当然自定义字体也并不是什么难事,只不过一开始厂商给的字体包有问题。那家伙好一顿纠结,我最开始也发现了是字体包的问题但是他们商务非要说可以用,并且在ps上是可以用的。我又让他们开发试了一下提供给我们的字体包,果不其然他们给的字体包有问题。最终还算顺利的给解决了。最近闲下来简单总结一下方便以后查阅和各位小伙伴使用。

原生实现

首先需要将字体添加到项目工程中,并配置plist

20e2d1cbfcf5

plist.jpg

这里可以添加多个item导入多个字体包

接下来我们需要得到字体的名称

打印查看字体名称

for(NSString *fontfamilyname in [UIFont familyNames])

{

NSLog(@"family:'%@'",fontfamilyname);

for(NSString *fontName in [UIFont fontNamesForFamilyName:fontfamilyname])

{

NSLog(@"\tfont:'%@'",fontName);

}

NSLog(@"-------------");

}

20e2d1cbfcf5

font.jpg

我们可以在控制台中查看我们要使用的字体font

下面我们可以调用一下字体看看具体的效果

//自定义字体

label.font = [UIFont fontWithName:@"FZLTXHK--GBK1-0" size:14];

//默认字体

label1.font = [UIFont systemFontOfSize:14];

很明显我们可以对比看不两种字体的不同

20e2d1cbfcf5

原生效果.jpg

这里我们原生的集成就OK了

当然[UIFont fontWithName:@"FZLTXHK--GBK1-0" size:14]这种写法太麻烦了,需要在很多地方修改。并且工程中有用到第三方sdk这种方式显然是不合适的。看到这里的小伙伴可能会说了用runtime来实现,这里我们可以使用类别 实现会更简单。

#pragma clang diagnostic push

#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"

+ (UIFont *)systemFontOfSize:(CGFloat)fontSize{

return [UIFont fontWithName:@"FZLTXHK--GBK1-0" size:fontSize];

}

+ (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize{

return [UIFont fontWithName:@"FZLTXHK--GBK1-0" size:fontSize];

}

#pragma clang diagnostic pop

由于app是混合开发除了原生的页面还会有h5页面。那么问题来了h5如何实现自定义字体?我们有的人肯定会说在h5工程中加入字体包。(⊙o⊙)… 不能不说这种方法是可以实现的,不可否认这将是最糟糕的做法。我们一个字体包有7.7M,可想而知用户体验该有多糟糕(可能会被骂死)......

这里简单说明一下实现的思路

拦截h5字体请求--->将本地的字体库返回给h5 这样可以很轻松的解决上面的一系列的问题

webView实现

自定义NSURLProtocol协议

+ (BOOL)canInitWithRequest:(NSURLRequest *)request{

NSLog(@"---->%@",request.URL);

NSString *scheme = [[request URL] scheme];

if ( ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||

[scheme caseInsensitiveCompare:@"https"] == NSOrderedSame ||

[scheme caseInsensitiveCompare:@"file"] == NSOrderedSame)){

if ([NSURLProtocol propertyForKey:RCBURLProtocolHandledKey inRequest:request]) {

return NO;

}

return YES;

}

return NO;

}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request{

return request;

}

- (void)startLoading{

NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];

[NSURLProtocol setProperty:@YES forKey:RCBURLProtocolHandledKey inRequest:mutableReqeust];

NSLog(@"URL-------->%@",self.request.URL);

if ([[self.request.URL absoluteString] hasSuffix:@"ttf"] ||

[[self.request.URL absoluteString] hasSuffix:@"TTF"]) {

//带格式

NSString *font = [self.request.URL.absoluteString lastPathComponent];

NSString *path = [[NSBundle mainBundle] pathForResource:font ofType:nil];

NSData *fontData = [NSData dataWithContentsOfFile:path];

NSURLResponse *response = [[NSURLResponse alloc] init];

[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];

[self.client URLProtocol:self didLoadData:fontData];

[[self client] URLProtocolDidFinishLoading:self];

}else{

self.connection = [NSURLConnection connectionWithRequest:mutableReqeust delegate:self];

}

}

- (void)stopLoading{

[self.connection cancel];

}

#pragma mark - NSURLConnection delegate

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{

[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];

//保存网络获取的数据和数据对象

self.data = [[NSMutableData alloc] init];

self.response = response;

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{

[[self client] URLProtocol:self didLoadData:data];

//累加数据

[self.data appendData:data];

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{

[[self client] URLProtocol:self didFailWithError:error];

}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{

[[self client] URLProtocolDidFinishLoading:self];

if (!self.response || [self.data length] == 0) {

return;

}

}

- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response{

if (response) {

// simply consider redirect as an error

NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorResourceUnavailable userInfo:nil];

[[self client] URLProtocol:self didFailWithError:error];

}

return request;

}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{

[[self client] URLProtocol:self didReceiveAuthenticationChallenge:challenge];

}

- (void)connection:(NSURLConnection *)connection didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{

[[self client] URLProtocol:self didCancelAuthenticationChallenge:challenge];

}

注册协议[NSURLProtocol registerClass:[BJRCBURLProtocol class]];

h5直接调用字体库

@font-face {

font-family: 'FZLTHK';

src: url('FZLTHK.TTF') format('truetype')

}

.p1 {

font-family: "FZLTHK";

font-size: 30pt;

color: blue;

}

.p2 {

font-size: 30pt;

color: blue

}

到这里app自定义字体就(原生+webView就全部实现了)

这里我写了一个简单的demo有需要的自己取

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐