wkwebview decidePolicyForNavigationAction being call after the long press recogniser ended

流过昼夜 提交于 2019-12-18 17:30:52

问题


I tried to override the original wkwebview actionsheet...

Firstly I disabled the original wkactionsheet by webView.evaluateJavaScript("document.body.style.webkitTouchCallout='none';", completionHandler: nil)

Then I initialise a long press gesture recogniser (and it works perfectly) and I created my own action sheet. I used decidePolicyForNavigationAction to get the clicked link urls:

func onLongPress(gestureRecognizer:UIGestureRecognizer){
        if gestureRecognizer.state == UIGestureRecognizerState.Began {
            longPressSwitch = true
        }
    }

func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
        if(navigationAction.navigationType == .LinkActivated) {
            longPressAcUrl = navigationAction.request.URL!.absoluteString
            if(longPressSwitch == true) {
                let ac = actionMenu(self)
                self.presentViewController(ac, animated: true) {

                }
                decisionHandler(.Cancel)
                longPressSwitch = false
            }
        }
        decisionHandler(.Allow)
    }

The problem is, the action sheet shows up after the finger is releasing (i.e., recogniser.state = .Ended) but I want it shows up like Chrome, which should be 0.5 or less seconds after the user pressing the link... (i.e., recogniser.state = .Begin), what can I do?

ps: this is my action sheet:

//Rebuild Wkactionsheet
    func actionMenu(sender: UIViewController) -> UIAlertController {
        let alertController = UIAlertController(title: "", message: longPressAcUrl, preferredStyle: .ActionSheet)
        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in

        }
        alertController.addAction(cancelAction)
        let openAction = UIAlertAction(title: "Open", style: .Default) { (action) in
            //...
        }
        alertController.addAction(openAction)
        let opentabAction = UIAlertAction(title: "Open in New Tab", style: .Default) { (action) in
            //...
        }
        alertController.addAction(opentabAction)
        let copyurlAction = UIAlertAction(title: "Copy Link URL", style: .Default) { (action) in
            //...
        }
        alertController.addAction(copyurlAction)

        return alertController
    }

also, if I tried to put

let ac = actionMenu(self)
self.presentViewController(ac, animated: true) {}

at onLongPress(), it works fine although this can't get URL (longPressAcUrl) from navigationAction.request.URL!.absoluteString!


回答1:


First of all, there's no need to mimic Chrome's behavior because there's little to no consequences to the whole experience. In fact, one could theorize your approach of having it show up after the finger is released is better than what Chrome and Safari is doing.

Why?

Because you are using the standard behavior of the standard long press recognition that is omnipresent throughout the entire ecosystem.

I believe Safari is showing up the action sheet while the user is pressing to give the illusion that everything is happening FAST.

Anyway, you can "fix" this by creating a custom UIWindow, implementing your own long press recognition and getting the elements of the HTML using saved coordinates. For a guide on how to create this entire behavior check this link: http://www.icab.de/blog/2010/07/11/customize-the-contextual-menu-of-uiwebview/comment-page-3/

(Objective-C)

Use UIGestureRecognizerStateBegan

A general bug: Websites will bypass the policy decision and will load the content when a touch ends.



来源:https://stackoverflow.com/questions/35499976/wkwebview-decidepolicyfornavigationaction-being-call-after-the-long-press-recogn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!