首页 文章

在WKWebView中使用自定义字体

提问于
浏览
47

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

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

但是,当我尝试使用WkWebView自定义字体无法正常工作时 . WkWebView显示随机默认字体 .

我尝试使用基本URL中的主束路径加载它并在css中使用font-face - WkWebView仍然显示随机字体 .

任何想法如何使自定义字体在WKWebView中工作?

对不起我的英语不好

5 回答

  • 8

    我面临同样的问题,在我的情况下,我可以使用 base64 encodingGCDWebServer 修复它 WITHOUT .

    Scenario:

    • WkWebView加载是通过字符串html

    • WkWebView正在使用本地.css

    • 字体是本地的,并在顶级项目中添加

    • 字体的条目在appName-info.plist中的键 Fonts provided by application 下提供


    Solution:

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

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

    DEMO PROJECT:

    GitHub Project Link

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

  • 3

    假设您将应用程序中的字体作为复制到目标包的资源嵌入,您可以通过将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>
    
  • 29

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

    css看起来像这样:

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

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

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

    - (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/

  • 20

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

    我通过在CSS中添加带有 @font-face 声明的字体来解决这个问题 . 有关如何执行此操作的MDN的详细信息,请参阅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委托中,根据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字符串中),你应该好好去 .

  • 23

    这是@Henrik Hartz的快速3版本的精彩答案:

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

相关问题