Using Custom Fonts in Wkwebview

Custom Font Not Working in WKWebView Swift

Reading the answers in the linked thread in DonMag's comment:

  • Using @font-face is mandatory

  • You need multiple @font-face declarations to use multiple font files as a single font family

  • You need to provide baseURL to make relative urls like url(OpenSans-Regular.ttf) work

So, try this:

    let htmlString = """
<style>
@font-face
{
font-family: 'Open Sans';
font-weight: normal;
src: url(OpenSans-Regular.ttf);
}
@font-face
{
font-family: 'Open Sans';
font-weight: bold;
src: url(OpenSans-Bold.ttf);
}
@font-face
{
font-family: 'Open Sans';
font-weight: 900;
src: url(OpenSans-ExtraBold.ttf);
}
@font-face
{
font-family: 'Open Sans';
font-weight: 200;
src: url(OpenSans-Light.ttf);
}
@font-face
{
font-family: 'Open Sans';
font-weight: 500;
src: url(OpenSans-Semibold.ttf);
}
</style>
(Utils.aboutUsText)
"""
webView.loadHTMLString(htmlString, baseURL: Bundle.main.bundleURL) //<-

Or you can use a separate css file if you prefer:

    let htmlString = """

(Utils.aboutUsText)
"""
webView.loadHTMLString(htmlString, baseURL: Bundle.main.bundleURL)

open-sans.css:

@font-face
{
font-family: 'Open Sans';
font-weight: normal;
src: url(OpenSans-Regular.ttf);
}
@font-face
{
font-family: 'Open Sans';
font-weight: bold;
src: url(OpenSans-Bold.ttf);
}
@font-face
{
font-family: 'Open Sans';
font-weight: 900;
src: url(OpenSans-ExtraBold.ttf);
}
@font-face
{
font-family: 'Open Sans';
font-weight: 200;
src: url(OpenSans-Light.ttf);
}
@font-face
{
font-family: 'Open Sans';
font-weight: 500;
src: url(OpenSans-Semibold.ttf);
}

Swift. Custom font for WebKit

To apply a custom font to an external HTML loaded in WKWebView (forced) Use the WKWebView HTML in the app if you want to display a custom font was added to the app in the CSS as shown below can be referred to (likely).

@font-face {

font-family: 'CustomFontFamily';

src: url('CustomFontFile.otf') format('opentype');
}
============================================

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {



@IBOutlet weak var webView: WKWebView!



override func viewDidLoad() {

super.viewDidLoad()

webView.navigationDelegate = self



let url = URL(string: "https://example.com/")

let request = URLRequest(url: url!)

webView.load(request)

}



func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {

//to encode the font data in the app in the Base64

let yuGothicMedium = getDataString(otf: "YuGothic-Medium")

let yuGothicBold = getDataString(otf: "YuGothic-Bold")



//embedded encoded font data in the Data URI scheme CSS

let cssString = """

@font-face {

font-family: 'YuGothic';

src: url('data:font/otf;base64,\(yuGothicMedium)') format('opentype');

font-weight: normal;

}

@font-face {

font-family: 'YuGothic';

src: url('data:font/otf;base64,\(yuGothicBold)') format('opentype');

font-weight: bold;

}

"""



//JavaScript to add the CSS as a style element

because//cssString is to enter a new line template literal

let customFontJs = """

var style = document.createElement('style');

style.innerHTML = `\(cssString)`;

document.head.appendChild(style);

"""



//executes the JavaScript

webView.evaluateJavaScript(customFontJs, completionHandler: nil)

}



func getDataString(otf: String) -> String {

let path = Bundle.main.path(forResource: otf, ofType: "otf")

let url = URL(fileURLWithPath: path!)

let data = try! Data(contentsOf: url)

return data.base64EncodedString()

}
}

WKWebView and Dynamic Type + Custom Fonts

I've finally managed to solve it, just add this chunk to the CSS

html {
font: -apple-system-body;
}

And leave body like this, with no font-size:

body {
font-family: 'MyCustomFont';
}

With just that, both things would work.

Use Custom Local Font in WKWebView

You did not provide a base URL when loading the HTML string, this will cause the font failing to load. Try accessing your bundle's main resource path, like this:

if let resourcePath = Bundle.main.resourcePath {
let url = URL.init(fileURLWithPath: resourcePath)
webView.loadHTMLString(getHtml(), baseURL: url)
}

WKWebView with custom font type and color

Firstly you can create a css file then add your fonts and styles inside this file

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

h1 {
font-family: 'FONT_FAMILY';
font-size: 20px;
font-weight: normal;
}

And load html string with css file

NSString *css = [NSString stringWithFormat:@""
""
""];
NSString *content = [NSString stringWithFormat:@""
"

%@

"
@"", @"YOUR_TEXT"];

[_wkWebView loadHTMLString:[NSString stringWithFormat:@"%@%@", css, content]
baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"YOUR_CSS_FILE" ofType:@"css"]]];

You can change the style name h1 with yours

Xcode: Load custom locally stored font for remote content in WKWebView

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

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.

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

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: [])
}

Now, I can use the locally in the app stored font in my WKWebView although the content is loaded remotely.

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>

Note:
The file you're loading remotely needs to have element, since the font is injected at the end of this.



Related Topics



Leave a reply



Submit