禁用UIWebView中的用户选择

Eng*_*epe 118 webkit uiwebview mobile-webkit ios4 ios

我有一个应用程序,我将内容加载到一个UIWebView并呈现此.我无法完全禁用用户交互,因为我希望用户能够单击链接.我只需要禁用用户选择.我发现你可以使用的互联网中的某个地方:

document.body.style.webkitUserSelect='none';
Run Code Online (Sandbox Code Playgroud)

我试着插入这个

[self.contentView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitUserSelect='none';"]; 
Run Code Online (Sandbox Code Playgroud)

webViewDidFinishLoad:

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

什么想法可能会出错?

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

Wri*_*sCS 276

以下是禁用选择的几种方法:

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

<style type="text/css">
* {
    -webkit-touch-callout: none;
    -webkit-user-select: none; /* Disable selection/copy in UIWebView */
}
</style>
Run Code Online (Sandbox Code Playgroud)

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

NSString * jsCallBack = @"window.getSelection().removeAllRanges();";    
[webView stringByEvaluatingJavaScriptFromString:jsCallBack];
Run Code Online (Sandbox Code Playgroud)

禁用"复制/粘贴"用户菜单:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

  • `canPerformAction`不会禁用剪切,复制,粘贴菜单.然后选择,全选菜单.如何解决这个问题?`-webkit-touch-callout`和`removeAllRanges`打破用户输入.无法使用所有提供的方法:( (7认同)
  • Engin,第一个在Mobile Safari,iOS 4.3.1中工作.但是WrightCS忘了添加选择器.要将其应用于所有元素,请使用星号,如:*{/*css go here*/} (4认同)
  • 将这些没有选择样式放在`*`全局范围中的问题是它会阻止用户在Web表单中输入.我发现通过放入`body`标签而得到了更好的结果. (4认同)

TPo*_*hel 103

我可以确认以下代码适用于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';"];
}
Run Code Online (Sandbox Code Playgroud)

也适用于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'")!
}
Run Code Online (Sandbox Code Playgroud)

  • 在iOS 7上确认!*注意:可以通过连接两个字符串将两个调用组合在一起.* (2认同)

小智 24

我在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 */

}
Run Code Online (Sandbox Code Playgroud)


pab*_*art 18

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

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

  • 如果你要这样做,不要忘记textarea! (2认同)

Bit*_*ttu 9

我不确定如何完成设置,但是为什么不在调用viewWillDisappear时清除pasteBoard.也许就像在你的appDelegate.m中:

[UIPasteboard generalPasteboard].string = nil;
Run Code Online (Sandbox Code Playgroud)

这将确保用户可能复制的任何数据,他们将无法将其粘贴到应用程序之外.

此外,像Engin一样,您可以覆盖包含uiwebview的控制器类中的canPerformSelector方法.


paw*_*ni1 7

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';"];
}
Run Code Online (Sandbox Code Playgroud)


Nar*_*mar 7

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

<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>
Run Code Online (Sandbox Code Playgroud)

如果您想要仅禁用锚点按钮标记,请使用此选项.

    a {-webkit-user-select: none; /* disable selection/Copy of UIWebView */
   -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
     }
Run Code Online (Sandbox Code Playgroud)


小智 6

    let longPress:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: nil, action: nil)
    longPress.minimumPressDuration = 0.2
    webView.addGestureRecognizer(longPress)
Run Code Online (Sandbox Code Playgroud)

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


Dmi*_*try 5

一周的伟大工作成果!如果要在许多页面上保存鼠标事件和用户输入,则所有其他答案都不正确.

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

[NSClassFromString(@"UIWebDocumentView") jr_swizzleMethod:@selector(canPerformAction:withSender:) withMethod:@selector(myCanPerformAction:withSender:) error:nil];
Run Code Online (Sandbox Code Playgroud)

NSObject的+ myCanPerformAction.h:

@interface NSObject (myCanPerformAction)

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

@end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

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

还有这个:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

  • 对此应该做些什么的解释会很好。特别是,我对为什么将您的手势称为singleTap却需要两次轻按感到困惑。 (2认同)