Xcode:为WKWebView中的远程内容加载自定义本地存储的字体 [英] Xcode: Load custom locally stored font for remote content in WKWebView
问题描述
我正在使用Xcode
和Swift
的最新版本.
I'm using the newest version of Xcode
and Swift
.
我有以下代码来加载HTML字符串并使用自定义字体,我以前是在Xcode中导入的:
I have the following code to load an HTML string and use a custom font, I prior imported in Xcode:
let html = """
<html>
<body>
<head>
<style>
@font-face
{
font-family: 'Blastimo';
src: local('Blastimo'), url('Blastimo.ttf') format('truetype');
}
</style>
</head>
<h1 style="font-family:'Blastimo';font-size:50px;">This is my test!</h1>
</body>
</html>
"""
webView.loadHTMLString(html, baseURL: Bundle.main.resourceURL)
以下代码允许我加载远程内容,例如从我的网络服务器上:
The following code allows me to load remote content, e.g. from my web server:
if let url = URL(string: "https://www.example.com") {
let request = URLRequest(url: url)
webView.load(request)
}
但是,我想到达的是:加载远程内容(如第二个代码中一样),但是将本地存储的自定义字体传递给此内容,如第一个代码中一样.
But, what I want to reach is: Load remote content, as in second code, but pass my locally stored custom font to this, as in the first code.
方法:我知道如何使用本地存储的字体加载HTML字符串,并且我知道如何不使用本地存储的字体加载远程内容.但是我不知道如何使用本地存储的字体加载远程内容.
Means: I know how to load an HTML string with a locally stored font and I know how to load remote content without a locally stored font. But I don't know how to load remote content with a locally stored font.
我尝试过:
webView.load(request, baseURL: Bundle.main.resourceURL)
但是这不起作用.会引发错误.
but this isn't working. It throws an error.
我尝试了很多,但是没有成功.我的最后一个想法是从远程内容中获取源代码,将其转换为字符串,向其中添加font-face
样式,并使用webView.loadHTMLString
加载它.这将使我能够显示远程内容,同时仍然能够使用webView.loadHTMLString(html, baseURL: Bundle.main.resourceURL)
加载该内容,以将本地存储的字体传递给它.
I tried so much but without success. My last idea is to get the source code from the remote content, convert it to a string, add font-face
style to it and load it with webView.loadHTMLString
. This will allow me to display the remote content while still being able to load this with webView.loadHTMLString(html, baseURL: Bundle.main.resourceURL)
to pass the locally stored font to it.
真的没有其他方法可以做到这一点吗?使用webView.load(request)
时,无法使用本地存储的字体吗?
Is there really no other way to do this? Is there no way to use my locally stored font when using webView.load(request)
?
推荐答案
我现在找到了一个解决方案.也许不是最好的,但是它正在起作用.
I found a solution now. Maybe not the best but it's working.
First, I converted the Blastimo.ttf
file to a base64 encoded CSS embedded font with this converter.
这给了我以下(或类似内容):
This gives me the following (or similar):
@font-face {
font-family: 'Blastimo';
src: url(data:application/x-font-woff;charset=utf-8;base64,HERE_COMES_THE_QUITE_LONG_BASE64_CODE_CREATED_BY_THE_CONVERTER) format('woff');
font-weight: normal;
font-style: normal;
}
我使用此代码(上面的代码来自转换器)将名为fonts.css
的文件导入/嵌入到我的Xcode项目中.导入/嵌入时应激活Add to targets
.
I imported/embedded a file called fonts.css
with this code (the code above from the converter) to my Xcode project. Add to targets
should be activated when importing/embedding.
在我的ViewController.swift
文件中,我具有以下代码(例如,在viewDidLoad()
中)以加载远程内容并调用本地CSS文件的函数:
In my ViewController.swift
file I have the following code (e.g. in viewDidLoad()
) to load the remote content and call the functions for the local CSS file:
if let url = URL(string: "https://www.example.com") {
let request = URLRequest(url: url)
webView.load(request)
}
injectToPage()
此外,这三个功能必须添加到ViewController.swift
文件的某个位置:
Additionally, these three functions have to be added somewhere to the ViewController.swift
file:
private func readFileBy(name: String, type: String) -> String {
guard let path = Bundle.main.path(forResource: name, ofType: type) else {
return "Failed to find path"
}
do {
return try String(contentsOfFile: path, encoding: .utf8)
} catch {
return "Unkown Error"
}
}
func injectToPage() {
let cssFile = readFileBy(name: "fonts", type: "css")
let cssStyle = """
javascript:(function() {
var parent = document.getElementsByTagName('head').item(0);
var style = document.createElement('style');
style.innerHTML = window.atob('\(encodeStringTo64(fromString: cssFile)!)');
parent.appendChild(style)})()
"""
let cssScript = WKUserScript(source: cssStyle, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
webView.configuration.userContentController.addUserScript(cssScript)
}
private func encodeStringTo64(fromString: String) -> String? {
let plainData = fromString.data(using: .utf8)
return plainData?.base64EncodedString(options: [])
}
现在,尽管内容是远程加载的,但我仍可以在WKWebView
中以本地方式在应用程序存储的字体中使用
Now, I can use the locally in the app stored font in my WKWebView
although the content is loaded remotely.
就我而言,我将其添加到(html或php)文件中,该文件是从Web服务器远程加载的:
In my case, I added this to the (html or php) file, that's loaded remotely from my web server:
<style>
* {
font-family:'Blastimo';
}
</style>
注意:
您正在远程加载的文件需要具有<head></head>
元素,因为字体是在此末尾注入的.
Note:
The file you're loading remotely needs to have <head></head>
element, since the font is injected at the end of this.
这篇关于Xcode:为WKWebView中的远程内容加载自定义本地存储的字体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!