WKWebView
iOS Development
WebView Content Size
Swift Programming
Apple Development

How to determine the content size of a WKWebView?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Determining the content size of a WKWebView is mostly a timing problem. If you read the size too early, you will get incomplete values; if you wait until navigation finishes and the layout settles, you can usually use either the embedded scroll view's content size or JavaScript that asks the document for its rendered height.

The Simplest Native Check

WKWebView contains an internal UIScrollView, and its contentSize is often the first thing developers look at.

swift
1import WebKit
2
3class ViewController: UIViewController, WKNavigationDelegate {
4    let webView = WKWebView()
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8        webView.navigationDelegate = self
9        view.addSubview(webView)
10        webView.frame = view.bounds
11        webView.loadHTMLString("<html><body><h1>Hello</h1><p>World</p></body></html>", baseURL: nil)
12    }
13
14    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
15        print(webView.scrollView.contentSize)
16    }
17}

This works well when the page has fully loaded and laid out by the time didFinish runs.

When contentSize Is Not Enough

Some pages change after initial load because of:

  • injected JavaScript
  • dynamic images
  • delayed fonts
  • client-side rendering

In those cases, didFinish may still be too early to trust the final height. A JavaScript query can be more explicit about the document's own layout.

Reading the Height With JavaScript

You can evaluate JavaScript after navigation completes:

swift
1func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
2    let script = "document.documentElement.scrollHeight"
3
4    webView.evaluateJavaScript(script) { result, error in
5        if let error = error {
6            print("JavaScript error:", error)
7            return
8        }
9
10        if let height = result as? CGFloat {
11            print("content height:", height)
12        } else if let height = result as? NSNumber {
13            print("content height:", CGFloat(truncating: height))
14        }
15    }
16}

This is often the most direct way to size the web view according to the rendered HTML document.

Adjusting a Height Constraint

If the web view is embedded in another scrolling layout, a common pattern is to update a height constraint once the content size is known.

swift
1@IBOutlet weak var webViewHeightConstraint: NSLayoutConstraint!
2
3func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
4    webView.evaluateJavaScript("document.documentElement.scrollHeight") { [weak self] result, _ in
5        if let value = result as? NSNumber {
6            self?.webViewHeightConstraint.constant = CGFloat(truncating: value)
7            self?.view.layoutIfNeeded()
8        }
9    }
10}

This is a standard way to make a non-scrolling WKWebView expand to fit its content.

Observe Changes for Dynamic Content

If the page content keeps changing, you may need to observe the scroll view's contentSize instead of measuring only once.

That approach is useful when:

  • the page loads images later
  • scripts inject additional HTML
  • the final content height depends on async activity

The important point is that content size is not always fixed at initial page load.

Width Affects Height

A web page's height depends on its rendering width. If the web view width changes because of device rotation or Auto Layout updates, the content height can change too.

So if you cache the size too early or reuse it after the width changes, the result may be wrong. Always measure in the layout state you actually care about.

Common Pitfalls

The biggest mistake is reading scrollView.contentSize before the page has finished loading and laid out.

Another issue is assuming didFinish always means "final visual size is settled." Dynamic pages can continue changing after navigation finishes.

Developers also forget that width changes affect rendered height. A height measured in portrait may be wrong in landscape.

Finally, if you are embedding the web view inside another scroll view, be clear about which layer should scroll. Mixing scrolling responsibilities often causes layout confusion.

Summary

  • 'WKWebView content size is usually read after navigation finishes, not immediately after loading starts.'
  • 'webView.scrollView.contentSize is a useful native measurement for many pages.'
  • 'evaluateJavaScript("document.documentElement.scrollHeight") is often the clearest way to get rendered document height.'
  • Update height constraints after measurement if the web view should expand with its content.
  • Re-measure when content changes dynamically or the web view width changes.

Course illustration
Course illustration

All Rights Reserved.