Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIWebView without Copy/Paste when displaying PDF files

Tags:

pdf

uiwebview

I have tried to disable Copy/Paste in UIWebView by using a category and overriding canPerformAction and returning NO for copy, cut and paste selectors.

It worked as expected when I loaded a webpage or all other document formats (e.g. docx, pptx, rtf, txt) but not when I loaded a PDF document into the UIWebView.

It seems like there is some different mechanism that handles PDF documents in UIWebView which handles/responds to Copy selector, and therefore I can not block it.

I also tried to disable user interaction for all the subviews of the UIWebView's UIScrollView, which worked fine for other document formats except PDF.

Can anyone help figuring out how to disable Copy in UIWebView for PDF documents as well?

like image 350
yairleisure Avatar asked Nov 27 '22 11:11

yairleisure


2 Answers

OK, so I've been experiencing the same problem myself and seem to find a solution, even if it's partial.

What I do is use a UILongPressGestureRecognizer to disable long press gestures that can lead to copy/paste.

The code:

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];
like image 116
Zubaba Avatar answered Dec 01 '22 22:12

Zubaba


This solution worked for me:

METHOD 1 - Detect Custom Long Presses

A) Create a subclass of UILongPressGestureRecogniser.

B) Include the canBePreventedByGestureRecognizer: method in your subclass, like this:

Header:

#import <UIKit/UIKit.h> 

@interface CustomLongPress : UILongPressGestureRecognizer

@end    

Implementation:

#import "CustomLongPress.h"

@implementation CustomLongPress

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

@end

That's the only code you need in the subclass.

C) Open up the view containing your uiwebview/pdf reader. Include your subclass: #import "CustomLongPress.h" and then add the custom UILongPressGestureRecogniser to your UIWebView, like this:

- (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) Detect the long press and switch your UIWebView's userInteraction Off then back On:

-(void)longPressDetected {

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

Apparently the reason this works is because the UIWebView captures long presses with its own gesture recognisers, to the exclusion of any additional gesture recongisers you've added. But subclassing your gesture recognisers and preventing their exclusion by returning "NO" to the canBePreventedByGestureRecognizer: method overrides the default behaviour.

Once you can detect the long presses on PDFs, switching the userInteraction Off then On again prevents the UIWebView from actioning its default behaviour, i.e. launching a "Copy/Define" UIMenu or, if long pressing over a link, launching a pop-up actionsheet with "Copy" and "Open" actions.

METHOD 2 - Catch UIMenu NSNotification

Alternatively, if you just want to block the "Copy/Define" UIMenu, (but not affect long presses), you can add this line (listening for UIMenuControllerDidShowMenuNotification) to your ViewDidLoad:

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

and then add this method, using the same userInteraction Off/On method as above:

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

First method taken from: https://devforums.apple.com/thread/72521?start=25&tstart=0, and second method from somewhere on Stack, sorry forgotten where. Please include if you know.

like image 39
Johnny Rockex Avatar answered Dec 01 '22 23:12

Johnny Rockex