UIWebView without Copy/Paste when displaying PDF files

前端 未结 8 948
醉话见心
醉话见心 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:38

    The UILongPressGestureRecognizer is located in the UIPDFPageView. To get access to this view look at the view hierarchy in the Debug menu, currently you can access this view like so once you load the pdf to the web view:

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

    Then to remove the Long Press use this method while passing in the pdfPageView:

    func removeLongPressFromView(view: UIView){
      if let gestures = view.gestureRecognizers{
        for gesture in gestures{
          if gesture is UILongPressGestureRecognzier{
            view.removeGestureRecognizer(gesture)
          }
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-10 20:39

    Looking for a Xamarin.iOS solution.

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

    The approach given by Zubaba might look like this:

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

    The open/copy/cancel menu still shows the first time a link is long held per PDF page. After that first long press, however, it properly does not show up for that page. That this is PDF page dependent does not give me confidence that there is a solution available.

    Johnny Rockex's solutions might look like this:

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

    and

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

    I was not able to get either to do anything. Helpfully someone else has done better with a Xamarin.iOS fix

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

    1.ios11 iphone6 Object-C Without Copy/Paste/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. Done!

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

    In case someone needs Zubaba's answer in 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.
    }
    
    0 讨论(0)
  • 2020-12-10 20:48

    Here is a modification to Zubaba's answer in Swift 3 that ended up working for me to eliminate warning. I changed assignment longPress.delegate = self to 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)
    
    0 讨论(0)
  • 2020-12-10 20:50

    Great answer Zubaba. I’m using a webView to display colored and bolded text and I had the same problem. I put your solution into a method and call it just after I initialize the webView. I don’t seem to need the delegate.

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