在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)
}
但是,当我 运行 它时,页面加载,滚动到该部分,然后跳回页面顶部。
我也试过设置 scrollView
的 contentOffset
,导致完全相同的问题
您应该在 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还没有加载完成。
我的解决方法如下:
- 使 ViewController 符合
WKWebViewNavigationDelegate
和 UIScrollViewDelegate
协议
class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate {
//..
}
- 向 ViewController 添加两个属性。一个将是一个 CGPoint 来存储滚动视图的内容偏移量,另一个将是一个布尔值来跟踪 Web 视图是否已完成加载,并且值为 false。
var position: CGPoint?
var webViewFinished = false
- 在
didFinish
委托方法中,将position
的值设置为滚动视图的内容偏移,将webViewFinished
设置为true
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
position = myWebView.scrollView.contentOffset
webViewFinished = true
}
- 在
scrollViewDidScroll
委托方法中,检查 Web 视图是否已完成加载。如果有,将滚动视图的内容偏移设置为 position
的值,并将 webViewFinished
设置为 false
(否则,每次用户滚动时,此代码将 运行 ).也不要忘记在 position
上进行可选链接!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if webViewFinished {
webViewFinished = false
if let p = position {
web.scrollView.setContentOffset(p, animated: false)
}
}
}
- 最后但同样重要的是,设置 Web View/Scroll 视图的委托
override func viewDidLoad(){
super.viewDidLoad()
myWebView.navigationDelegate = self
myWebView.scrollView.delegate = self
}
使用下面的代码,我试图将 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)
}
但是,当我 运行 它时,页面加载,滚动到该部分,然后跳回页面顶部。
我也试过设置 scrollView
的 contentOffset
,导致完全相同的问题
您应该在 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还没有加载完成。
我的解决方法如下:
- 使 ViewController 符合
WKWebViewNavigationDelegate
和UIScrollViewDelegate
协议
class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate {
//..
}
- 向 ViewController 添加两个属性。一个将是一个 CGPoint 来存储滚动视图的内容偏移量,另一个将是一个布尔值来跟踪 Web 视图是否已完成加载,并且值为 false。
var position: CGPoint?
var webViewFinished = false
- 在
didFinish
委托方法中,将position
的值设置为滚动视图的内容偏移,将webViewFinished
设置为true
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
position = myWebView.scrollView.contentOffset
webViewFinished = true
}
- 在
scrollViewDidScroll
委托方法中,检查 Web 视图是否已完成加载。如果有,将滚动视图的内容偏移设置为position
的值,并将webViewFinished
设置为false
(否则,每次用户滚动时,此代码将 运行 ).也不要忘记在position
上进行可选链接!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if webViewFinished {
webViewFinished = false
if let p = position {
web.scrollView.setContentOffset(p, animated: false)
}
}
}
- 最后但同样重要的是,设置 Web View/Scroll 视图的委托
override func viewDidLoad(){
super.viewDidLoad()
myWebView.navigationDelegate = self
myWebView.scrollView.delegate = self
}