How to disable the magnifying glass in UIWebview?
-
08-01-2021 - |
题
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?
解决方案
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).
其他提示
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.
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';"];
}
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.
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.