ios 在 UIWebView 中禁用用户选择

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5995210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:54:42  来源:igfitidea点击:

Disabling user selection in UIWebView

iosuiwebviewwebkitios4mobile-webkit

提问by Engin Kurutepe

I have an app where I load content to a UIWebViewand 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:

我有一个应用程序,可以将内容加载到 aUIWebView并显示它。我无法完全禁用用户交互,因为我希望用户能够单击链接。我只需要禁用用户选择。我在互联网上的某个地方找到了你可以使用的:

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

I tried inserting this as

我尝试将其插入为

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

in webViewDidFinishLoad:

webViewDidFinishLoad:

However, it does not work. I am still able to select and copy text inside the WebView.

但是,它不起作用。我仍然可以在 WebView 中选择和复制文本。

Any Ideas what might be going wrong?

任何想法可能会出错?

Update: This only seems to happen starting with iOS 4.3

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

回答by WrightsCS

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:

以编程方式加载以下 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];
}

回答by TPoschel

I can confirm that the following code works in iOS 5.0 - 8.0.

我可以确认以下代码适用于 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:

也适用于 iOS 9 及更高版本。这是快速代码:

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

回答by Johno Scott

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, :

我在适用于 Android/iPhone 的网络应用程序中使用此技术(与 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 */

}

回答by pablobart

I like the WrightsCS solution but I will use this so the users can still using the copy,paste and select actions on inputs

我喜欢 WrightsCS 解决方案,但我会使用它,因此用户仍然可以对输入使用复制、粘贴和选择操作

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

回答by Bittu

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:

我不确定设置是如何完成的,但是为什么在调用 viewWillDisappear 时不清除 pasteBoard。也许类似于您的 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 所说,您可以覆盖包含 uiwebview 的控制器类中的 canPerformSelector 方法。

回答by pawelini1

TPoschel answer is corrent but in my case order was important.

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

回答by Narsingh Tomar

I can confirm this will definitely work for you.

我可以确认这肯定对你有用。

<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>

If you want Disable only anchor button tag use this.

如果您只想禁用锚按钮标签,请使用它。

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

回答by Dmitry

Result of the great work for one week! All others answers are incorrect if you want to save mouse events and user input on many pages.

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

1) Swizzle method (by rentzsch/jrswizzlelibrary):

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

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

NSObject+myCanPerformAction.h:

NSObject+myCanPerformAction.h:

@interface NSObject (myCanPerformAction)

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

@end

NSObject+myCanPerformAction.m:

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) Place UIWebView on UIView and add a code:

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

And this one:

和这个:

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

回答by Samrat Pramanik

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

Simply add this code to your viewDidLoad(). User can click on link but can not copy the content.

只需将此代码添加到您的 viewDidLoad()。用户可以点击链接但不能复制内容。

回答by Scooter

The first solution given worked perfectly for me...until I loaded a .pdf into my UIWebView.

给出的第一个解决方案对我来说非常有效......直到我将 .pdf 加载到我的 UIWebView 中。

Loading a .doc file worked perfectly, but loading a .pdf resulted in the following line of code no longer having the desired effect and the copy/define menu popped up again on a long touch by the user.

加载.doc文件非常完美,但加载一个.pdf导致下面的代码行不再具有所期望的效果和复制/定义在长触摸用户再次弹出菜单。

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

After another bout of hair pulling I found this answer on here by Johnny Rockex and it worked like a champ. UIWebView without Copy/Paste when displaying PDF files

在又一次拉头发之后,我在 Johnny Rockex 上找到了这个答案,它的效果非常好。 显示PDF文件时没有复制/粘贴的UIWebView

Many thanks to him for this easy to implement, genius solution!!

非常感谢他这个易于实施的天才解决方案!!