Disabling user selection in UIWebView
Solution 1
Here are a few ways to disable selection:
Add the following to your mobile web documents
<style type="text/css">
* {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/copy in UIWebView */
}
</style>
Programmatically load the following Javascript code:
NSString * jsCallBack = @"window.getSelection().removeAllRanges();";
[webView stringByEvaluatingJavaScriptFromString:jsCallBack];
Disable the Copy / Paste user menu:
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(copy:) ||
action == @selector(paste:)||
action == @selector(cut:))
{
return _copyCutAndPasteEnabled;
}
return [super canPerformAction:action withSender:sender];
}
Solution 2
I can confirm that the following code works in iOS 5.0 - 8.0.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// Disable user selection
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
// Disable callout
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}
Also works for iOS 9 and later. Here's the swift code:
func webViewDidFinishLoad(webView: UIWebView) {
// Disable user selection
webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitUserSelect='none'")!
// Disable callout
webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitTouchCallout='none'")!
}
Solution 3
I am using this technique in a web app for Android / iPhone (packaged with Trigger.IO) and found it would only work with the chaining syntax for the :not() pseudo-class, :
*:not(input):not(textarea) {
-webkit-user-select: none; /* disable selection/Copy of UIWebView */
-webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
}
Solution 4
I like the WrightsCS solution but I will use this so the users can still using the copy,paste and select actions on inputs
<style type="text/css">
*:not(input,textarea) {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/Copy of UIWebView */
}
</style>
Solution 5
I am not sure how the setup is done, but why dont you just clear the pasteBoard when viewWillDisappear is called. Maybe something like in your appDelegate.m:
[UIPasteboard generalPasteboard].string = nil;
this will make sure whatever data user might have copied, they will not be able to paste it outside of the app.
Also, like Engin said you can override the canPerformSelector method in the controller class that contains the uiwebview.
Engin Kurutepe
Indie developer and founder Fifteen Jugglers Software building Aufwind, SolarWatch and CallTap. You can best reach me on Twitter: @ekurutepe
Updated on May 28, 2020Comments
-
Engin Kurutepe almost 4 years
I have an app where I load content to a
UIWebView
and present this. I cannot disable user interaction completely because I want the user to be able to click links. I just need to disable user selection. I found somewhere in the Internets that you can use:document.body.style.webkitUserSelect='none';
I tried inserting this as
[self.contentView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitUserSelect='none';"];
in
webViewDidFinishLoad:
However, it does not work. I am still able to select and copy text inside the WebView.
Any Ideas what might be going wrong?
Update: This only seems to happen starting with iOS 4.3
-
Engin Kurutepe about 13 yearsHi Wright, unfortunately the first one does not work in iOS 4.3. Where should I implement the second one? I tried
webViewDidFinishLoad:
but it didn't work. I also tried the third method in my view controller who is responsible for the UIWebView. It keep returningNO
but this doesn't prevent the UIWebView from showing the menu. -
Deepak Danduprolu about 13 yearsExtend
UIWebView
using a category. -
fisherwebdev almost 13 yearsEngin, the first one does work in Mobile Safari, iOS 4.3.1. But WrightCS forgot to add the selector. To apply it to all elements, use the asterisk, like: * { /*css goes here*/ }
-
spatical over 12 yearsAdding the style worked perfectly in removing the menu that appeared when tapholding on a link inside of my PhoneGap app.
-
RK- over 12 yearsThis is one of the best solutions. This can be set in - (void)applicationDidEnterBackground:(UIApplication *)application event handler. And this ensures that no data goes out of the App.
-
Dmitry over 11 years
canPerformAction
doesn't disable Cut, Copy, Paste menu. And Select, Select All menu. How to fix this?-webkit-touch-callout
andremoveAllRanges
break user input. Can't use all provided methods:( -
Ryan over 11 yearsIf you're going to do this, don't forget textarea!
-
Mark Rummel over 11 yearsI'm using jQuery Mobile and Phonegap Build and this worked for me. I first tried,
*:not(input,textarea) {-webkit-touch-callout: none; -webkit-user-select: none;}
, but that didn't do the trick for me. Thanks! -
Norman H almost 11 years@Krishan, are you 100% certain that will stop screenshots as well?
-
Bigood over 10 yearsConfirmed on iOS 7! Note : It's possible to group the two calls in one by concatenating the two strings.
-
binary_falcon over 9 yearsI like this solution, but since it stays on the pasteboard while the application is active, another (malicious) application running in the background thread can access the general pasteboard while it has data in it.
-
arlomedia over 9 yearsSome explanation of what this is supposed to do would be nice. In particular, I'm confused about why your gesture is called singleTap but requires two taps.
-
dbank about 9 yearsWelcome to stackoverflow. Does answer really add value to this old question? Please review How to Answer.
-
Aaron D about 9 yearsConsider expanding your answer (providing some small code example) to increase the value of your answer. Also, answers containing 'it works for me' don't really inspire confidence - better to present the answer as-is and then troubleshoot if someone asks for clarification on your answer.
-
SwathiK about 9 yearsHow to add this in my document <style type="text/css"> * { -webkit-touch-callout: none; -webkit-user-select: none; /* Disable selection/copy in UIWebView */ } </style> Shall i do copy paste in the document
-
David Douglas almost 9 yearsThe problem with putting these no select styles in
*
global scope is that it stops user input in web forms. I found I got better results by placing inside thebody
tag instead. -
Kaiyuan Xu over 8 yearsthis works for me in iOS 9 + Xcode 7 GM, other methods I tried are just useful in iOS 7&8
-
DwarDoh over 8 yearsOn iOS 9.x an empty call out appears at top of screen after long press, even when using above.
-
Lakshay Dulani about 8 yearshow can I use the above code..I just know JS; don't have any idea how I can edit objective c code or change phonegap plugin..if anybody can help
-
ΩlostA over 7 yearsWork with iOS 9 & 10 perfect guy!
-
Hamzah Malik over 6 yearswouldnt this also remove data not from the app? Perhaps get the data at appear and set it back to that on disappear would work better
-
bleepmeh over 5 years@DeepakDanduprolu I have extended
UIWebView
and used the debugger to make sure it reaches to the function and it returnsNO
, but copy paste and cut still show up on the menu. Do you have an example possibly? -
Chris Ho over 4 yearsSave my time, Thank you!!