UIWebView without Copy/Paste when displaying PDF files

前端 未结 8 949
醉话见心
醉话见心 2020-12-10 20:21

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

相关标签:
8条回答
  • 2020-12-10 20:55

    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.

    0 讨论(0)
  • 2020-12-10 20:56

    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];
    
    0 讨论(0)
提交回复
热议问题