【问题标题】:Disabling user selection in UIWebView在 UIWebView 中禁用用户选择
【发布时间】:2011-08-25 02:39:39
【问题描述】:

我有一个应用程序,我在其中将内容加载到 UIWebView 并呈现。我不能完全禁用用户交互,因为我希望用户能够单击链接。我只需要禁用用户选择。我在 Internet 的某个地方找到了您可以使用的地方:

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

我尝试将其插入为

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

webViewDidFinishLoad:

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

任何想法可能出了什么问题?

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

【问题讨论】:

    标签: ios uiwebview webkit ios4 mobile-webkit


    【解决方案1】:

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

    也适用于 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'")!
    }
    

    【讨论】:

    • 在 iOS 7 上确认! 注意:可以通过连接两个字符串将两个调用组合为一个。
    • 在 iOS 9.x 上,长按后屏幕顶部会出现一个空的呼出,即使在上面使用时也是如此。
    • 如何使用上面的代码..我只知道JS;不知道如何编辑目标 c 代码或更改 phonegap 插件..如果有人可以提供帮助
    • 与 iOS 9 & 10 完美的人一起工作!
    【解决方案2】:
        let longPress:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: nil, action: nil)
        longPress.minimumPressDuration = 0.2
        webView.addGestureRecognizer(longPress)
    

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

    【讨论】:

      【解决方案3】:

      对我来说,我打算通过LongPressGestureUIWebView 获取图像的NSData

      但是放大镜和复制/粘贴/剪切总是发生在我的函数执行之前。

      我发现了这个:

      这意味着,放大镜和复制/粘贴/剪切需要0.5s才能执行,所以如果你的func可以在0.49s内执行,DONE!

      self.longPressPan.minimumPressDuration = 0.3
      

      【讨论】:

      • 这适用于我在 iOS 9 + Xcode 7 GM 中,我尝试的其他方法在 iOS 7&8 中才有用
      【解决方案4】:

      使用网页视图交互功能

         webView.userInteractionEnabled = false
      

      对我有用

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

      【讨论】:

      • 欢迎来到stackoverflow。答案真的为这个老问题增加了价值吗?请查看How to Answer
      • 考虑扩展您的答案(提供一些小代码示例)以增加您的答案的价值。此外,包含“它对我有用”的答案并不能真正激发信心 - 最好按原样提供答案,然后在有人要求澄清您的答案时进行故障排除。
      【解决方案5】:

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

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

      还有这个:

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

      【讨论】:

      • 对这应该做什么的一些解释会很好。特别是,我很困惑为什么你的手势被称为 singleTap 但需要两次点击。
      【解决方案6】:

      我可以确认这绝对适合你。

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

      【讨论】:

        【解决方案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';"];
        }
        

        【讨论】:

          【解决方案8】:

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

          加载 .doc 文件效果很好,但加载 .pdf 导致以下代码行不再具有所需的效果,并且在用户长按时再次弹出复制/定义菜单。

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

          在又一次拉扯头发之后,我在 Johnny Rockex 上找到了这个答案,它就像一个冠军。 UIWebView without Copy/Paste when displaying PDF files

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

          【讨论】:

            【解决方案9】:

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

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

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

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

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

            【讨论】:

            • 使用类别扩展UIWebView
            • Engin,第一个在 Mobile Safari,iOS 4.3.1 中工作。但是 WrightCS 忘记添加选择器了。要将其应用于所有元素,请使用星号,例如:* { /*css go here*/ }
            • 添加样式非常适合删除在我的 PhoneGap 应用程序内点击链接时出现的菜单。
            • canPerformAction 不会禁用剪切、复制、粘贴菜单。并选择,全选菜单。如何解决这个问题? -webkit-touch-calloutremoveAllRanges 中断用户输入。不能使用所有提供的方法:(
            • 将这些无选择样式放在* 全局范围内的问题在于它会阻止用户在 Web 表单中输入。我发现通过放置在 body 标记内得到了更好的结果。
            【解决方案10】:

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

            【讨论】:

            • 我正在使用 jQuery Mobile 和 Phonegap Build,这对我有用。我第一次尝试,*:not(input,textarea) {-webkit-touch-callout: none; -webkit-user-select: none;},但这对我没有用。谢谢!
            【解决方案11】:

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

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

            【讨论】:

            • 如果你要这样做,别忘了 textarea!
            【解决方案12】:

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

            [UIPasteboard generalPasteboard].string = nil;
            

            这将确保用户复制的任何数据都无法粘贴到应用程序之外。

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

            【讨论】:

            • 这是最好的解决方案之一。这可以在 - (void)applicationDidEnterBackground:(UIApplication *)application 事件处理程序中设置。这可以确保没有数据从应用程序中流出。
            • @Krishan,您是否 100% 确定也会停止截屏?
            • 我喜欢这个解决方案,但是由于它在应用程序处于活动状态时停留在粘贴板上,因此在后台线程中运行的另一个(恶意)应用程序可以访问通用粘贴板,而其中有数据。跨度>
            • 这是否也会从应用程序中删除数据?也许在出现时获取数据并将其设置回消失时会更好
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-11-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-07
            • 1970-01-01
            • 2023-03-27
            相关资源
            最近更新 更多