13

How can I disable the magnifying glass that appears when you hold the touch on a UIWebView? I don't want to to disable user interaction but I don't want the webview to show that zoom glass. Any Ideas?

Filip Radelic
  • 26,607
  • 8
  • 71
  • 97
Mashhadi
  • 3,004
  • 3
  • 46
  • 80

5 Answers5

7

No, the loupe is inextricably linked to selection. To disable it, you will have to disable selection entirely (you can use -webkit-user-select: none to do that).

jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • 1
    if an input/textarea gets focused and blurs without user touching "Done" on the keyboard, this trick will no longer work. (iOS 7) – vilicvane Jul 07 '14 at 17:26
6

Because the accepted solution did not work for me, I had to look for other options and I found one.
Note that I don't know if Apple approves this technique. Use it at your own fear and risk.

(Ours wasn't rejected; I don't think Apple cares that much about you messing with UIWebView internals, but be warned.)

What I did was recursively walk down UIWebView subviews and enumerate their gestureRecognizers. Whenever I encounter a UILongPressGestureRecognizer, I set its enabled to NO.

This gets rid of the magnifying glass altogether and obviously disables any default long-press functionality.

It seems like iOS re-enables (or re-creates) these gesture recognizers whenever user begins to edit text.
Well, I don't mind using magnifying glass in text fields so I don't disable them immediately.

Instead, I wait for blur event on my text elements, and when it occurs, I walk the subview tree again.
Simple as that, and it works.

Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • What the hell's with the downvote? Is there something wrong with documenting solutions that successfully worked for us? – Dan Abramov Apr 02 '14 at 09:01
  • This sounds legit to me. – Mark Sep 21 '15 at 04:23
  • Someone created a cordova plugin for this: https://github.com/EddyVerbruggen/cordova-plugin-ios-longpress-fix/blob/master/src/ios/LongPressFix.m – Aggressor Oct 14 '15 at 17:49
  • For Capacitor, take a look at: https://github.com/ionic-team/capacitor/discussions/3208 and https://github.com/Nikita-schetko/capacitor-suppress-longpress-gesture – Vojto Oct 06 '21 at 08:46
3

I have found that -webkit-user-select: none; alone doesn't do the trick. Instead I have found a quite undocumented property -webkit-touch-callout

What I usually do with Phonegap apps is this:

body, body * {
    -webkit-user-select: none !important;
    user-select: none !important;
    -webkit-user-callout: none !important;
    -webkit-touch-callout: none !important;
}
input, textarea {
    -webkit-user-select: text !important;
    user-select: text !important;
    -webkit-user-callout: default !important;
    -webkit-touch-callout: default !important;
}

Somewhere it was mentioned that -webkit-user-callout is a legacy version of -webkit-touch-callback, I have put this in just in case.

Rob Fox
  • 5,355
  • 7
  • 37
  • 63
3

Because I don't know how to use -webkit-user-select: none I looked for other ways. And I stumble into this Customize the contextual menu of UIWebView then I combined it with -webkit-user-select: none.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
   [webView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitUserSelect='none';"];
}
jovhenni19
  • 450
  • 2
  • 8
  • 24
  • 1
    `-webkit-user-select: none` is a CSS attribute. So you need to either use the code you posted, or if you have access to the web content displayed in your webview, you'd include it with your CSS. – Ben Feb 24 '12 at 07:07
0

For our Cordova & Swift project I did:

override init!(webView theWebView: UIWebView!)
    {            
        super.init(webView: theWebView)

        removeLoupe()
    }

    /**
        Removes the magnifying glass by adding a long press gesture that overrides the inherent one that spawns
        a the loupe by default.
    */
    private func removeLoupe()
    {
        let views = webView?.subviews
        if (views == nil || views?.count == 0)
        {
            return
        }

        let longPress = UILongPressGestureRecognizer(target: self, action: "handleLongPress:")
        longPress.minimumPressDuration = 0.045
        longPress.allowableMovement = 100.0

        for view in views!
        {
            if (view.isKindOfClass(UIScrollView))
            {
                let subViews = view.subviews
                let browser = subViews[0]
                browser.addGestureRecognizer(longPress)
                break;
            }
        }
    }

    /**
       Hack to override loupe appearence in webviews.
    */
    func handleLongPress(sender:UILongPressGestureRecognizer)
    {

    }

Note that this is my CDVPlugin class (or rather my custom version of it).

Make sure your config.xml file has:

<feature name="CustomCDVPlugin">
    <param name="ios-package" value="CustomCDVPlugin" />
    <param name="onload" value="true" />
</feature>

This will ensure the init() method is called.

Aggressor
  • 13,323
  • 24
  • 103
  • 182