4

我试图通过使用类别并覆盖 canPerformAction 并为复制、剪切和粘贴选择器返回 NO 来禁用 UIWebView 中的复制/粘贴。

当我加载网页或所有其他文档格式(例如 docx、pptx、rtf、txt)时,它按预期工作,但当我将 PDF 文档加载到 UIWebView 时却没有。

似乎有一些不同的机制可以处理 UIWebView 中的 PDF 文档,它处理/响应复制选择器,因此我无法阻止它。

我还尝试禁用 UIWebView 的 UIScrollView 的所有子视图的用户交互,这对于除 PDF 之外的其他文档格式都适用。

任何人都可以帮助弄清楚如何在 UIWebView 中为 PDF 文档禁用复制吗?

4

8 回答 8

17

好的,所以我自己也遇到过同样的问题,并且似乎找到了解决方案,即使它是部分的。

我所做的是使用 UILongPressGestureRecognizer 禁用可能导致复制/粘贴的长按手势。

编码:

UILongPressGestureRecognizer* longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; // allocating the UILongPressGestureRecognizer

longPress.allowableMovement=100; // Making sure the allowable movement isn't too narrow

longPress.minimumPressDuration=0.3; // This is important - the duration must be long enough to allow taps but not longer than the period in which the scroll view opens the magnifying glass

longPress.delegate=self; // initialization stuff
longPress.delaysTouchesBegan=YES;
longPress.delaysTouchesEnded=YES;

longPress.cancelsTouchesInView=YES; // That's when we tell the gesture recognizer to block the gestures we want 

[webView addGestureRecognizer:longPress]; // Add the gesture recognizer to the view and scroll view then release
[[webView scrollView] addGestureRecognizer:longPress]; 
[longPress release];
于 2012-10-15T03:59:31.493 回答
5

这个解决方案对我有用:

方法 1 - 检测自定义长按

A) 创建一个 UILongPressGestureRecogniser 的子类。

B)canBePreventedByGestureRecognizer:在您的子类中包含该方法,如下所示:

标题:

#import <UIKit/UIKit.h> 

@interface CustomLongPress : UILongPressGestureRecognizer

@end    

执行:

#import "CustomLongPress.h"

@implementation CustomLongPress

- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer*)preventedGestureRecognizer {
 return NO;
}

@end

这是子类中唯一需要的代码。

C) 打开包含您的 uiwebview/pdf 阅读器的视图。包括您的子类:#import "CustomLongPress.h"然后将自定义 UILongPressGestureRecogniser 添加到您的 UIWebView,如下所示:

- (void)viewDidLoad
{ 
   [super viewDidLoad];

   //Load UIWebView etc

   //Add your custom gesture recogniser
   CustomLongPress * longPress = [[CustomLongPress alloc] initWithTarget:self action:@selector(longPressDetected)];
   [pdfWebView addGestureRecognizer:longPress];

}

D)检测长按并关闭您的 UIWebView 的 userInteraction 然后再打开:

-(void)longPressDetected {

NSLog(@"long press detected");
[pdfWebView setUserInteractionEnabled:NO];
[pdfWebView setUserInteractionEnabled:YES];
}

显然,这是因为 UIWebView 使用自己的手势识别器捕获长按,排除您添加的任何其他手势识别器。但是将手势识别器子类化并通过向方法返回“NO”来防止它们被排除canBePreventedByGestureRecognizer:会覆盖默认行为。

一旦您可以检测到对 PDF 的长按,将 userInteraction 关闭然后再打开会阻止 UIWebView 执行其默认行为,即启动“复制/定义”UIMenu,或者,如果长按链接,则启动弹出操作表使用“复制”和“打开”操作。

方法 2 - 捕获 UIMenu NSNotification

或者,如果您只想阻止“复制/定义”UIMenu(但不影响长按),您可以将此行(监听 UIMenuControllerDidShowMenuNotification)添加到您的 ViewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuShown) name:UIMenuControllerDidShowMenuNotification object:nil];

然后添加此方法,使用与上述相同的 userInteraction Off/On 方法:

-(void)menuShown {
    NSLog(@"menu shown");
    [pdfWebView setUserInteractionEnabled:NO];
    [pdfWebView setUserInteractionEnabled:YES];   
}

第一种方法取自:https ://devforums.apple.com/thread/72521?start=25&tstart=0 ,第二种方法取自 Stack 上的某个地方,抱歉忘记在哪里了。如果您知道,请包括在内。

于 2012-12-19T19:57:22.017 回答
3

很好的答案祖巴巴。我正在使用 webView 显示彩色和粗体文本,我遇到了同样的问题。我将您的解决方案放入一个方法中,并在初始化 webView 后立即调用它。我似乎不需要代表。

self.textView = [[UIWebView alloc] initWithFrame:textFrame];
[self longPress:self.textView];

- (void)longPress:(UIView *)webView {

UILongPressGestureRecognizer* longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress)]; // allocating the UILongPressGestureRecognizer

longPress.allowableMovement=100; // Making sure the allowable movement isn't too narrow
longPress.minimumPressDuration=0.3; // This is important - the duration must be long enough to allow taps but not longer than the period in which the scroll view opens the magnifying glass

longPress.delaysTouchesBegan=YES;
longPress.delaysTouchesEnded=YES;

longPress.cancelsTouchesInView=YES; // That's when we tell the gesture recognizer to block the gestures we want

[webView addGestureRecognizer:longPress]; // Add the gesture recognizer to the view and scroll view then release
[webView addGestureRecognizer:longPress];

}

- (void)handleLongPress {

}
于 2013-02-12T01:54:46.630 回答
3

如果有人需要 Zubaba 在 Swift 3 中的回答;

let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
longPress.allowableMovement = 100
longPress.minimumPressDuration = 0.3
longPress.delegate = self
longPress.delaysTouchesBegan = true
longPress.delaysTouchesEnded = true
longPress.cancelsTouchesInView = true
yourWebView.addGestureRecognizer(longPress)
yourWebView.scrollView.addGestureRecognizer(longPress)


func handleLongPress() {
     // Show some alert to inform user or do nothing.
}
于 2017-01-13T08:27:35.807 回答
1

这是对 Zubaba 在 Swift 3 中的回答的修改,最终帮助我消除了警告。我将作业更改longPress.delegate = selflongPress.delegate = self as? UIGestureRecognizerDelegate.

    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
    longPress.allowableMovement = 100
    longPress.minimumPressDuration = 0.3
    longPress.delegate = self as? UIGestureRecognizerDelegate
    longPress.delaysTouchesBegan = true
    longPress.delaysTouchesEnded = true
    longPress.cancelsTouchesInView = true
    webView.addGestureRecognizer(longPress)
    webView.scrollView.addGestureRecognizer(longPress)

    webView.loadRequest(request)
于 2017-06-27T16:39:52.570 回答
0

1.ios11 iphone6 Object-C无复制/粘贴/lookUp/share

2.

viewDidLoad{
    .......
    [self setupExclude];
}

- (void)setupExclude{
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPG)];
    longPress.minimumPressDuration = 0.2;
    [self.webview addGestureRecognizer:longPress];

    UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:nil];
    singleTapGesture.numberOfTapsRequired = 1;
    singleTapGesture.numberOfTouchesRequired  = 1;
    [self.webview addGestureRecognizer:singleTapGesture];

    UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(longPG)];
    doubleTapGesture.numberOfTapsRequired = 2;
    doubleTapGesture.numberOfTouchesRequired = 1;
    [self.webview addGestureRecognizer:doubleTapGesture];
    [singleTapGesture requireGestureRecognizerToFail:doubleTapGesture];
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
    BOOL res = [super canPerformAction:action withSender:sender];
    UIMenuController.sharedMenuController.menuVisible = NO;
    self.webview.userInteractionEnabled = NO;
    self.webview.userInteractionEnabled = YES;
    return res;
}
- (void)longPG{
    UIMenuController.sharedMenuController.menuVisible = NO;
    self.webview.userInteractionEnabled = NO;
    self.webview.userInteractionEnabled = YES;
}

3. 完成!

于 2017-10-31T06:53:52.943 回答
0

寻找 Xamarin.iOS 解决方案。

var longPressGestureRecognizer = new CustomLongPressGestureRecognizer ((UILongPressGestureRecognizer obj) => 
{
  Console.WriteLine ("CustomLongPressGestureRecognizer action");
});
webView.AddGestureRecognizer (longPressGestureRecognizer);

Zubaba 给出的方法可能如下所示:

public class ZubabaLongPressGestureRecognizer : UIKit.UILongPressGestureRecognizer
{
    public ZubabaLongPressGestureRecognizer (Action<UILongPressGestureRecognizer> action)
      : base (action)
    {
        AllowableMovement = 100;
        MinimumPressDuration = 0.3;
        DelaysTouchesBegan = true;
        DelaysTouchesEnded = true;
        CancelsTouchesInView = true;
    }
}

打开/复制/取消菜单仍然显示第一次长时间保存每个 PDF 页面的链接。但是,在第一次长按之后,它不会正确显示在该页面上。这取决于 PDF 页面并不能让我相信有可用的解决方案。

Johnny Rockex 的解决方案可能如下所示:

public class RockexLongPressGestureRecognizer : UIKit.UILongPressGestureRecognizer
{
    public RockexLongPressGestureRecognizer(UIKit.UIWebView webView, Action<UILongPressGestureRecognizer> action) :
        base(UserInteractionAction(webView) + action)
    {

    }

    private static Action<UILongPressGestureRecognizer> UserInteractionAction(UIKit.UIWebView webView)
    {
        return (UILongPressGestureRecognizer obj) =>
         {
             webView.UserInteractionEnabled = false;
             webView.UserInteractionEnabled = true;
         };
    }

    public override bool CanPreventGestureRecognizer(UIGestureRecognizer preventedGestureRecognizer)
    {
        return false;
    }
}

notificationToken1 = UIMenuController.Notifications.ObserveMenuFrameDidChange (Callback);
notificationToken2 = NSNotificationCenter.DefaultCenter.AddObserver(UIMenuController.DidShowMenuNotification, Callback);

我什么也做不了。帮助其他人在 Xamarin.iOS 修复方面做得更好

于 2017-05-09T17:32:41.333 回答
0

UILongPressGestureRecognizer 位于 UIPDFPageView 中。要访问此视图,请查看 Debug 菜单中的视图层次结构,目前您可以在将 pdf 加载到 Web 视图后访问此视图:

let pdfPageView = myWebView.scrollview?.subviews[0]?.subviews[0]

然后在传递 pdfPageView 时删除长按使用此方法:

func removeLongPressFromView(view: UIView){
  if let gestures = view.gestureRecognizers{
    for gesture in gestures{
      if gesture is UILongPressGestureRecognzier{
        view.removeGestureRecognizer(gesture)
      }
    }
  }
}
于 2016-03-15T22:08:57.700 回答