iOS设置非系统自定义字体- 原生app自定义字体和H5自定义字体

湛宏旷
2023-12-01

一、App更改自定义字体

按照常规方法更改即可
(1).将字体文件放入工程
(2).在info.plist中增加Fonts provided by application 数组类型,并将添加的字体文件添加
(3).找到字体文件对应的具体的我们要用的字体名字

let fontFamilies = UIFont.familyNames
for fontFamily in fontFamilies {
    let fontNames = UIFont.fontNames(forFamilyName: fontFamily)
    print("\(fontFamily): \(fontNames)")
}

(4).在设置font的地方利用

UIFont(name: "具体的字体名", size: 15)

二、H5自定义字体

2.1 原生与H5混编交互原理

H5端通过css设置html标签的字体,移动端与H5交互基于协议,实现相应协议方法,可以通过注入的方式修改远程网页H5的css代码。

2.2 H5自定义字体的方式

2.2.1一种是UIWebView可以URLProtocol拦截请求,如使用本地图片的方式一样,当检测到是ttf将本地库读出来,直接将data返回。

关键代码如下:

1、自定义CustomURLProtocol: NSURLProtocol

2、在AppDelegate注册

[NSURLProtocol registerClass:[CustomURLProtocol class]];

3、在加载H5的Web ViewController里添加方法

- (void)startLoading

{

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

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

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

// fontName

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

NSString *path = [[NSBundle mainBundle] pathForResource:fontName ofType:@"ttf"];

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];

}   }

鉴于 iOS端苹果明确发文截止2020年底不能再用UIWebView,而WKWebView不能使用URLProtocol拦截请求,故该方法舍弃。

2.2.2 iOS端配置的字体文件流数据转成base64 ,然后base64通过css注入到webView页面

 1、将需要使用的自定义字体文件Add到工程,勾选Copy items if needs并Add to targets

2、在iOS与H5交互的webView代理方法didFinish navigation:方法里调用配置自定义字体方法

关键代码如下:

private func coustomH5Font(_ fontStr:String) {//传入需要支持的自定义字体文件名

let currentBundle = Bundle.main

let fileUrl = currentBundle.path(forResource: fontStr, ofType: "ttf")!

let fileData = NSData(contentsOfFile: fileUrl) as Data?

let boldFont = fileData?.base64EncodedString(options: [])

var javascript = ""

javascript += String(

format: " var boldcss = '@font-face { font-family: \"%@\"; src: url(data:font/ttf;base64,%@) format(\"truetype\");} *{font-family: \"%@\" !important;}'; var body = document.getElementsByTagName('body')[0], style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = boldcss; body.appendChild(style);", fontStr, boldFont!, fontStr)

webView.jl_evaluateJavaScript(javascript) { (_: Any?, _: Error?) in

}     }

3、H5端需要在font-family里添加支持的自定义字体名称

4、运行测试 :app已配置自定义字体 和网络下载的任意非系统自定义字体

1)网络下载的测试字体大小23.8MB,而当字体文件较大时,即单个字体文件大或者某个页面需要支持的自定义字体种类多时,页面加载字体的变化过程很明显,先显示页面,然后变更字体后再显示,视觉体验较差。

2)字体替换后,app端内嵌的H5页面若有使用过特殊字体的图标会出现展示不出来的情况。

 

参考文章如下:https://www.jianshu.com/p/6eca3374435e感谢

 类似资料: