Determining the content size of a WKWebView
In one of my recent projects, I had to use a web view to display an HTML string with local CSS and custom font. The web view had to be embedded inside a scroll view along with a couple of other views. It also had to have a height adjusted to the content it was displaying. My goal was to create something like this:
I had already done this in one of my previous projects so I figured I’d reuse the same code.
The problem was that the code was using a
UIWebView instead of the newer
WKWebView. Since iOS 8,
UIWebView was replaced with a much more powerful and well structured
WKWebView, and since iOS 12
UIWebView was officially deprecated. That meant that I had to reimplement the feature.
I’ve put all the code in an example project on GitHub so you can follow along.
Loading HTML string
For loading HTML strings into the web view,
loadHTMLString(_:baseURL:) method. The HTML string that I was getting from backend did not have
<BODY> tags so I had to manually add them. The method for loading the HTML looked like this:
<HEAD>tag has to have
viewportmetadata which is important for the correct calculation of the content height of the web view.
loadHTMLStringhas to be the main bundle URL because we will be loading our local custom font.
Loading local CSS
Loading local CSS file into HTML was pretty easy in
UIWebView. You only had to add
<link rel='stylesheet' href='/path/to/css' type='text/css'> in the
WKWebView the process is a bit more complicated because it requires CSS to be injected after HTML loads. We can do that by utilizing the
webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) method of the
First, we load the contents of the
<style> tag into web view’s HTML.
The problem with this approach is that the web view loads HTML, displays it and after that applies CSS. That transition is visible by the user which is not good.
Fortunately, there is a better approach. We can use
WKUserScript that represents a script that can be injected into a webpage, and
WKUserContentController that allows us to inject that script into the web view. These objects will be used inside a
Using this approach, CSS will be loaded just after HTML loads and there won’t be a transition that can be noticed by the user.
Adding custom font in CSS
To add custom fonts in Xcode, I suggest you follow Apple’s tutorial. After adding the font, we need to load it into the web view using CSS. To use custom fonts in CSS we need to use the
@font-face CSS rule:
This way, we have defined our custom font and it can now be used in CSS:
Calculating web view’s content height
scrollHeight of the document in the web view. We’ll do that in the delegate method to make sure that the web view finished loading before calculation:
In this blog post, we’ve gone through one use case of
WKWebView and analyzed the problems that can occur. We can see that the new API gives us much more flexibility and stability compared to the deprecated