简体   繁体   中英

WKWebView weird scroll behavior when long press to select text if contentInset is set

I am having an issue that long press and selecting text on the WKWebView will randomly scroll the web view. This behavior happens when I set the contentInset.top property of the scroll view of the web view.

[Screenshot]

  1. Long press on the text. The green area is a native UIView https://ibb.co/P4LqgBB
  2. After dragging on the text, WKWebView scrolls itself down unexpectedly https://ibb.co/r5KR4JB

Since my application need to show the native view above the web view potion, this behavior really frustrates my users when they need to copy and paste text from the web view.

Below is the minimum code that you can use to reproduce the issue. I tried this on iPhone 8 iOS 12.2 using Xcode 10.2. The issue occurs when webView.scrollView.contentInset.top = 100 is set. Moreover, if you change the value to something like 1000 , where the contentInset.top is longer than the phone's screen size, long press will cause the web view to scroll instantly.

 override func viewDidLoad() {
        super.viewDidLoad()

        // Create WKWebView
        let webView = WKWebView(frame: .zero)
        webView.translatesAutoresizingMaskIntoConstraints = false
        webView.scrollView.contentInsetAdjustmentBehavior = .never
        webView.clipsToBounds = false
        webView.scrollView.bounces = false

        // Create Native UIView
        let nativeView = UIView(frame: .zero)
        nativeView.translatesAutoresizingMaskIntoConstraints = false
        nativeView.backgroundColor = .green

        // Add WebView to the view
        view.addSubview(webView)

        webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        webView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        webView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        // Set contentInset to give blank space for native view
        webView.scrollView.contentInset.top = 100

        // Add the native view as webView scrollView's child
        webView.scrollView.addSubview(nativeView)
        nativeView.leadingAnchor.constraint(equalTo: webView.leadingAnchor).isActive = true
        nativeView.trailingAnchor.constraint(equalTo: webView.trailingAnchor).isActive = true
        nativeView.topAnchor.constraint(equalTo: webView.scrollView.topAnchor,
                                        constant: -100).isActive = true
        nativeView.heightAnchor.constraint(equalToConstant: 100).isActive = true

        // Load the webpage
        let url = URL(string: "https://www.apple.com")!
        let request = URLRequest(url: url)
        webView.load(request)
    }

I expect the long press and scroll behave like when contentInset.top is not set.

Does anyone know how to fix this issue?

Please add first UIScrollViewDelegate,WKNavigationDelegate,WKUIDelegate delegates in your viewcontroller and add below delegates.

// MARK: - WKWebView Delegate

private func webView(webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
    print(error.localizedDescription)
}

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
  //  print("Strat to load")
}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
   // print("finish to load")
    let javascriptStyle = "var css = '*{-webkit-touch-callout:none;-webkit-user-select:none}'; var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; style.appendChild(document.createTextNode(css)); head.appendChild(style);"
    webView.evaluateJavaScript(javascriptStyle, completionHandler: nil)
}

// MARK: - UIScrollViewDelegate

func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
    return nil
}

I have faced same issue and above code working fine for me. Hope it will help to you. @Chui

WKWebView creates a-lot of problems if the css isn't done clean enough.

I sugest moving back to UIWebView, it should fix all your problems

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM