显示PDF文件时没有复制/粘贴的UIWebView

时间:2012-10-07 10:57:46

标签: pdf uiwebview

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

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

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

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

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

8 个答案:

答案 0 :(得分: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];

答案 1 :(得分: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 Off然后再打开:

-(void)longPressDetected {

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

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

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

方法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的某处,抱歉遗忘在哪里。如果您知道,请提供。

答案 2 :(得分: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 {

}

答案 3 :(得分:2)

如果有人需要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.
}

答案 4 :(得分:1)

这是对Zubaba在Swift 3中的回答的修改,最终为我消除了警告。我将作业longPress.delegate = self更改为longPress.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)

答案 5 :(得分:0)

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

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

然后删除Long Press在传入pdfPageView:

时使用此方法
func removeLongPressFromView(view: UIView){
  if let gestures = view.gestureRecognizers{
    for gesture in gestures{
      if gesture is UILongPressGestureRecognzier{
        view.removeGestureRecognizer(gesture)
      }
    }
  }
}

答案 6 :(得分:0)

寻找Xamarin.iOS解决方案。

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

Zubaba给出的方法可能如下:

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

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

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

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

In [1]: product = [(0, 0, 0, 0, 0), (0, 0, 0, 0, 1), (0, 0, 0, 0, 2), (0, 0, 0,
   ...:  0, 3), (0, 0, 0, 1, 0), (0, 0, 0, 1, 1), (0, 0, 0, 1, 2), (0, 0, 0, 1,
   ...:  3), (0, 0, 0, 2, 0), (0, 0, 0, 2, 1)]

In [2]: product[3][4]  # get the fifth value of the fourth element of 'product'
Out[2]: 3

我无法做任何事情。通过Xamarin.iOS修复,帮助其他人做得更好

答案 7 :(得分: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。完成!