課題
WKWebViewでなんらかのWebページを表示している時に、ページ全体の高さや幅などを取得したい場合がある。簡単に検索して実装をすると、
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // ここで高さを取得する }
このようなコードを書くことになる。しかし、Webページは画像の読み込みやiframe、JavaScriptの影響で後からサイズが変わっていくので、このコードでは正しくサイズ取得するのは困難である。
解決方法
WKWebViewはUIScrollViewを内包しており、UIScrollViewはKVOに対応しているため、これを利用する。
import UIKit import WebKit final class ViewController: UIViewController { @IBOutlet weak var webView: WKWebView! private var observer: NSKeyValueObservation? override func viewDidLoad() { super.viewDidLoad() observer = webView.scrollView.observe(\.contentSize, options: [.new], changeHandler: { scrollView, value in guard let newValue = value.newValue else { return } print(newValue.height, newValue.width) }) let request = URLRequest(url: URL(string: "https://fromatom.hatenablog.com/entry/2023/03/08/100000")!) webView.load(request) } }
これによって、WKWebViewで表示したWebページのサイズが変更が監視されるため、サイズが変わるたびに print(newValue.height, newValue.width)
が呼ばれるようになる。
なお、KVOは古い書き方もあるが、Swift4から使えるようになったこのBlock-baseのものを使うのが推奨される。