在WKWebView中使用自定义字体

2020/12/01 01:22 · ios ·  · 0评论

我在应用中使用自定义字体。它们被复制到包中并硬编码到appName-info.plist。这种字体可以在整个应用程序和UIWebView中完美运行。

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

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

我试图用基本URL中的主捆绑路径加载它,并在CSS中使用font-face-WkWebView仍然显示随机字体。

有什么想法可以使自定义字体在WKWebView中工作吗?

对不起我的英语不好

我遇到了同样的问题,就我而言,无需使用base64编码GCDWebServer即可解决此问题

场景:

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

解:

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

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

演示项目:

GitHub项目链接

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

假设您将字体作为复制到目标包中的资源嵌入到应用程序中,则可以通过将NSURL作为baseURL传递到WKWebView对字体的访问权限

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

并定义没有任何前置路径元素的字体面孔url,这又使WKWebKit成为baseURL的前缀

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

由于我不想为此而使用另一个第三方,并且由于我自己构建html字符串,因此我采取了使用字体的第一部分,而不是使用远程或本地文件的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/

更新:现在可以使用WKURLSchemeHandler

@interface MySchemeHandler : NSObject <WKURLSchemeHandler>
@end

@implementation MySchemeHandler

- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask
{
  NSURL *url = urlSchemeTask.request.URL;
  NSString *mimeType = [NSString stringWithFormat:@"text/%@", url.pathExtension]; //or whatever you need
  NSURLResponse *response = [[NSURLResponse alloc] initWithURL:url MIMEType:mimeType expectedContentLength:-1 textEncodingName:nil];
  [urlSchemeTask didReceiveResponse:response];
  NSData *data = [self getResponseData];
  [urlSchemeTask didReceiveData:data];
  [urlSchemeTask didFinish];
}
@end

在配置WKWebView实例时:

WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
MySchemeHandler *handler = [[MySchemeHandler alloc] init];
[config setURLSchemeHandler:handler forURLScheme:@"myScheme"];
//now pass the config to your WKWebView

------旧答案----------

我的猜测是,WKWebView由于它现在处于单独的进程(XPC)中,因此不能再访问特定于该应用程序的字体。

我通过@font-face在CSS中添加带有声明的字体来解决此问题有关如何执行此操作的MDN,请参见此处

例:

@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字符串而不是本地文件)。根据对此问题的评论,我能够使用GCDWebServer来使本地HTML文件工作。在您的应用程序委托中,按照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声明放入styleHTML文件中的元素中(如果真的只需要加载字符串,则放入HTML字符串中),您应该会做得很好。

这是@Henrik Hartz出色的答案的迅速3版本:

loadHTMLString(htmlString, baseURL: NSURL.fileURL(withPath: Bundle.main.bundlePath))
本文地址:http://ios.askforanswer.com/zaiwkwebviewzhongshiyongzidingyiziti.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!