在 UIWebView 中禁用用户选择

我有一个应用程序,我加载内容到一个 UIWebView和目前这一点。我不能完全禁用用户交互,因为我希望用户能够点击链接。我只需要禁用用户选择。我在网上找到了你可以用的东西:

document.body.style.webkitUserSelect='none';

I tried inserting this as

[self.contentView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitUserSelect='none';"];

webViewDidFinishLoad:

但是,它不工作。我仍然能够选择和复制文本内的 WebView。

知道哪里出了问题吗?

更新: 这似乎只发生在 iOS 4.3开始

97869 次浏览

下面是禁用选择的一些方法:

将以下内容添加到您的移动网络文档中

<style type="text/css">
* {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/copy in UIWebView */
}
</style>

以编程方式加载以下 Javascript 代码:

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];
}

我不确定这个设置是如何完成的,但是为什么不在 viewWillDisaper 被调用的时候清除粘贴板呢。也许在你的应用程序中是这样的:

[UIPasteboard generalPasteboard].string = nil;

这将确保无论用户可能复制了什么数据,他们都不能将其粘贴到应用程序之外。

另外,就像 Engin 说的,您可以在包含 uiwebview 的控制器类中覆盖 canPerformSelector 方法。

我可以确认以下代码在 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';"];
}

同样适用于 iOS9和更高版本。以下是快速代码:

func webViewDidFinishLoad(webView: UIWebView) {
// Disable user selection
webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitUserSelect='none'")!
// Disable callout
webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitTouchCallout='none'")!
}

我喜欢 WrightsCS 解决方案,但是我将使用它,这样用户仍然可以使用复制、粘贴和选择输入上的操作

<style type="text/css">
*:not(input,textarea) {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/Copy of UIWebView */
}
</style>

这是一周伟大工作的结果!如果您想在许多页面上保存鼠标事件和用户输入,所有其他的答案都是不正确的。

1) Swizzle 方法(通过 Rentzsch/jrswizzle库) :

[NSClassFromString(@"UIWebDocumentView") jr_swizzleMethod:@selector(canPerformAction:withSender:) withMethod:@selector(myCanPerformAction:withSender:) error:nil];

NSObject + myCanPerformAction.h:

@interface NSObject (myCanPerformAction)


- (BOOL)myCanPerformAction:(SEL)action withSender:(id)sender;


@end

NSObject + myCanPerformAction.m:

#import "NSObject+myCanPerformAction.h"


@implementation NSObject (myCanPerformAction)


- (BOOL)myCanPerformAction:(SEL)action withSender:(id)sender {
if (action == @selector(copy:)) {
return [self myCanPerformAction:action withSender:sender];
}
if (action == @selector(paste:)) {
return [self myCanPerformAction:action withSender:sender];
}
return NO;
}


@end

2)在 UIView 上放置 UIWebView 并添加代码:

    UITapGestureRecognizer* singleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];
singleTap.numberOfTapsRequired = 2;
singleTap.numberOfTouchesRequired = 1;
singleTap.delegate = self;
[self.view addGestureRecognizer:singleTap];

还有这个:

- (void)handleSingleTap:(UIGestureRecognizer*)gestureRecognizer {
return;
}


- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
UITapGestureRecognizer *gesture = (UITapGestureRecognizer *)otherGestureRecognizer;
if (gesture.numberOfTapsRequired == 2) {
[otherGestureRecognizer.view removeGestureRecognizer:otherGestureRecognizer];
}
}
return YES;
}

我在 Android/iPhone 的一个 web 应用程序中使用了这种技术(包含 Trigger.IO) ,发现它只能用于: not ()伪类的链接语法:

*: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 */


}

给出的第一个解决方案非常适合我... ... 直到我将一个. pdf 文件加载到我的 UIWebView 中。

正在加载。文档文件工作得很好,但是加载一个。Pdf 导致以下代码行不再有预期的效果,复制/定义菜单在用户长时间触摸后再次弹出。

    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];

在又一次拔头发之后,我在这里找到了这个答案,作者是约翰尼 · 洛克斯(Johnny Rockex) ,这个答案非常有效。显示 PDF 文件时不复制/粘贴 UIWebView

非常感谢他这么容易实现,天才的解决方案! !

TPoschel 的回答是正确的,但对我来说顺序很重要。

// this works - locks selection and callout
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}


// this doesn't work - locks only callout
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
}

我可以肯定,这一定会为你工作。

<style type="text/css">
*: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 */
}
</style>

如果希望只禁用锚按钮标记,请使用。

    a {-webkit-user-select: none; /* disable selection/Copy of UIWebView */
-webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
}

使用网页视图交汇功能

   webView.userInteractionEnabled = false

It works for me

PS: 记住当你希望用户可以再次与 webview 交互时启用交互

对于我来说,我打算从 UIWebView通过 LongPressGesture获取图像的 NSData

But the Magnifier and Copy/Paste/Cut always occur before my func execute.

我发现了这个: enter image description here

这意味着,放大镜和复制/粘贴/剪切需要0.5秒来执行,所以如果你的函数可以在0.49秒内执行,完成!

self.longPressPan.minimumPressDuration = 0.3
    let longPress:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: nil, action: nil)
longPress.minimumPressDuration = 0.2
webView.addGestureRecognizer(longPress)

只需将此代码添加到 viewDidLoad ()。用户可以单击链接,但无法复制内容。