Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting contentInset of WKWebView scrollView causes page jump to top

After setting contentInset of WKWebView, I found if I use default swipe gesture to navigate between pages, WKWebView will not reserve the contentInset and just jump to the top, does anyone know how to resolve that? Thanks!

enter image description here

My sample code:

import UIKit
import WebKit

class ViewController: UIViewController {

    private lazy var webView: WKWebView = {
        let view = WKWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
        view.allowsBackForwardNavigationGestures = true
        view.scrollView.contentInsetAdjustmentBehavior = .never
        view.scrollView.contentInset = UIEdgeInsets(top: 50, left: 0, bottom: 0, right: 0)

        view.navigationDelegate = self
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.addSubview(self.webView)

        if let url = URL(string: "http://www.wikipedia.org") {
            self.webView.load(URLRequest(url: url))
        }
    }

}
like image 762
Haibara Ai Avatar asked Sep 15 '25 09:09

Haibara Ai


1 Answers

If you set contentInset for a scrollview of WKWebView, you need set another property of WKWebview with same value. view.setValue(UIEdgeInsets, forKey: "_obscuredInsets")

Refer to : https://opensource.apple.com/source/WebKit2/WebKit2-7600.1.4.11.10/ChangeLog

private lazy var webView: WKWebView = {
        let view = WKWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
        view.allowsBackForwardNavigationGestures = true
        view.scrollView.contentInsetAdjustmentBehavior = .never
        let edgeInsets = UIEdgeInsets(top: 50, left: 0, bottom: 0, right: 0)
        view.setValue(edgeInsets, forKey: "_obscuredInsets")
        view.scrollView.contentInset = edgeInsets
        return view
    }()

If you set contentInsetAdjustmentBehavior = .automatic, there will have a extra edge of status bar. You also need to add the status bar height to obscuredInsets.

view.scrollView.contentInsetAdjustmentBehavior = . automatic
webView.scrollView.contentInset = UIEdgeInsets(top: 50, left: 0, bottom: 0, right: 0)
webView.setValue(UIEdgeInsets(top: 50 + 44, left: 0, bottom: 0, right: 0), forKey: "_obscuredInsets")

44 is the height of status bar(safeArea).


Checked the newest WKWebView: https://github.com/WebKit/webkit/blob/master/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

Now need add an extra property: _haveSetObscuredInsets

webView.setValue(true, forKey: "_haveSetObscuredInsets")

like image 113
Leo Lee Avatar answered Sep 16 '25 23:09

Leo Lee