在WKWebView中使用scrollIntoVIew跳转到页面顶部

Using scrollIntoVIew in WKWebView jumps to top of page

使用下面的代码,我试图将 HTML 加载到 WKWebview 中,然后将其滚动到特定元素。

  let url = Bundle.main.url(forResource: "TestHTML", withExtension: "html")!
    myWebView.loadFileURL(url, allowingReadAccessTo: url)
    myWebView.evaluateJavaScript("document.getElementById('4').scrollIntoView(true);") {[weak self] (result, error) in
        print("result: \(result)")
        print (error)
    }

但是,当我 运行 它时,页面加载,滚动到该部分,然后跳回页面顶部。

我也试过设置 scrollViewcontentOffset,导致完全相同的问题

您应该在 webview 委托方法中编写 javascript 评估代码 didFinish 导航

extension WebViewController: WKNavigationDelegate {

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("Finished navigating to url \(webView.url)")
        webView.evaluateJavaScript("document.getElementById('4').scrollIntoView(true);") { (any, error) in
            dump(error)
            print(any)
        }
    }
}

并且不要忘记设置 webview delgate

myWebView.navigationDelegate = self

我几个月前发布了这个问题,虽然 在一个演示项目中工作,但它在另一个项目中对我不起作用 - 它会转到偏移量,然后再返回顶部。

问题好像是在webView(didFinish) 运行s的代码中,web view确实加载完成了,但是scroll view还没有加载完成。

我的解决方法如下:

  1. 使 ViewController 符合 WKWebViewNavigationDelegateUIScrollViewDelegate 协议
class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate {
//..
}
  1. 向 ViewController 添加两个属性。一个将是一个 CGPoint 来存储滚动视图的内容偏移量,另一个将是一个布尔值来跟踪 Web 视图是否已完成加载,并且值为 false。
var position: CGPoint?
var webViewFinished = false
  1. didFinish委托方法中,将position的值设置为滚动视图的内容偏移,将webViewFinished设置为true
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        position = myWebView.scrollView.contentOffset
        webViewFinished = true
    }
  1. scrollViewDidScroll 委托方法中,检查 Web 视图是否已完成加载。如果有,将滚动视图的内容偏移设置为 position 的值,并将 webViewFinished 设置为 false(否则,每次用户滚动时,此代码将 运行 ).也不要忘记在 position 上进行可选链接!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if webViewFinished {
            webViewFinished = false
            if let p = position {
                web.scrollView.setContentOffset(p, animated: false)
            }
        }
    }
  1. 最后但同样重要的是,设置 Web View/Scroll 视图的委托
override func viewDidLoad(){
    super.viewDidLoad()
    myWebView.navigationDelegate = self
    myWebView.scrollView.delegate = self
}