在WKWebView中使用自定义字体

时间:2014-09-11 10:33:42

标签: ios css fonts uiwebview wkwebview

我在我的应用中使用自定义字体。它们被复制到bundle并硬编码到appName-info.plist。 这种字体在整个应用程序和UIWebView中都能很好地工作。

我正在加载htmlString [webView loadHTMLString:htmlString baseURL:nil]; 我在webView中使用这种字体与css: fontFamily: fontName

但是当我尝试使用WkWebView自定义字体时无效。 WkWebView显示随机默认字体。

我尝试在基本网址中使用主捆绑路径加载它并在css中使用font-face - WkWebView仍然显示随机字体。

如何让自定义字体在WKWebView中运行?

抱歉我的英文

5 个答案:

答案 0 :(得分:33)

我遇到了同样的问题,在我的情况下,我可以使用 base64编码 GCDWebServer 修复没有

<强>情境:

  • WkWebView加载是通过字符串html
  • WkWebView使用的是本地.css
  • 字体是本地的,并在顶级项目中添加
  • 字体条目在密钥Fonts provided by application
  • 下的appName-info.plist中提供

<强>解决方案:

在顶级的.css中添加字体,如下所示

@font-face
{
    font-family: 'FontFamily';
    src: local('FontFamily'),url('FontFileName.otf') format('opentype');
}

DEMO PROJECT:

GitHub Project Link

注意:新的演示应用程序运行可能需要2-3秒,我已经测试了它的长html字符串,它与UIWebView一样,没有滞后。 WKWebView中的相同字体可能看起来比UIWebView小。

答案 1 :(得分:26)

假设您将应用程序中的字体作为复制到目标软件包的资源嵌入,您可以通过将NSURL作为baseURL传递给它的文件夹来授予WKWebView访问字体的权限

NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSURL *bundleUrl = [NSURL fileURLWithPath:bundlePath];
[self.webView loadHTMLString:HTML baseURL:bundleUrl];

并定义没有任何前面路径元素的font-face url,这反过来使WKWebKit添加了baseURL

<style>
  @font-face { font-family: 'Custom Font'; src: url('CustomFont.ttf'); }
  ...
</style>

答案 2 :(得分:20)

由于我不想仅仅为了那个而使用另一个第三方,因为我自己构建了html字符串,所以我采用了第一部分使用font-face而不是使用url来远程或本地文件,我将字体转换为base64。

css看起来像这样:

@font-face {
    font-family: 'FONTFAMILY';
    src: url(data:font/ttf;base64,FONTBASE64) format('truetype');
}

您可以使用您需要的系列替换FONTFAMILY,并使用从该字体生成的基本64字符串替换FONTBASE64。

如果你需要在你的应用程序中创建base64字符串,你可以使用它,只需提供文件名和类型(我用它来获取其他文件,所以它更通用,你可以删除ofType参数并使用@&#34; ttf&#34;代替):

- (NSString*)getBase64FromFile:(NSString*)fileName ofType:(NSString*)type
{
    NSString * filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:type];

    // Create NSData object
    NSData *nsdata = [NSData dataWithContentsOfFile:filePath];

    // Get NSString from NSData object in Base64
    NSString *base64Encoded = [nsdata base64EncodedStringWithOptions:0];

    return base64Encoded;
}

如果您只想做一次然后将其保存在某个文件中,您可以使用任何将文件转换为base64的在线网站,如下所示:http://www.opinionatedgeek.com/dotnet/tools/base64encode/

答案 3 :(得分:9)

我的猜测是WKWebView无法再访问特定于应用程序的字体,因为它现在处于一个单独的进程(XPC)中。

我通过在CSS中添加带@font-face声明的字体来解决这个问题。有关如何执行此操作的详细信息,请参阅here

示例:

@font-face
{
  font-family: "MyFontFace";
  src:url('url-to-font.ttf');
}

//And if you have a font with files with different variants, add this:
@font-face
{
  font-family: "MyFontFace";
  src:url('url-to-italic-variant.ttf');
  font-style:italic;
}

但是这将引用WKWebView无法做到的本地文件(我假设您已经发现了这个,因为您正在加载HTML字符串而不是本地文件)。根据对this question的评论,我能够使用GCDWebServer来获取本地HTML文件。在您的app delegate中,根据GitHub上的GCDWebServer wiki将相关文件添加到项目中之后:

GCDWebServer *server = [[[GCDWebServer alloc]init]autorelease];
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
[server addGETHandlerForBasePath:@"/"
   directoryPath:bundlePath indexFilename:nil
   cacheAge:0 allowRangeRequests:YES];
[server startWithPort:8080 bonjourName:nil];

现在,您可以在包中引用名为test.html的HTML文件,如下所示:

NSString *path = @"http://localhost:8080/test.html";
NSURL *url = [NSURL URLWithString:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[myWebView loadRequest:request];

将前面提到的@font-face声明放在HTML文件的style元素中(如果你真的需要加载一个字符串,则放在HTML字符串中),你应该好好去。

答案 4 :(得分:4)

这是@Henrik Hartz的一个快速3版本的真棒答案:

loadHTMLString(htmlString, baseURL: NSURL.fileURL(withPath: Bundle.main.bundlePath))