UIWebView без копирования/вставки при отображении PDF файлов

Я попытался отключить Копировать/Вставить в UIWebView с помощью категории и переопределить canPerformAction и вернуть НЕТ для селекторов копирования, вырезания и вставки.

Он работал, как ожидалось, при загрузке веб-страницы или всех других форматов документов (например, docx, pptx, rtf, txt), но не тогда, когда я загрузил PDF-документ в UIWebView.

Похоже, существует некоторый другой механизм, который обрабатывает документы PDF в UIWebView, который обрабатывает/отвечает на Селектор копирования, и поэтому я не могу его заблокировать.

Я также попытался отключить взаимодействие с пользователем для всех подпрограмм UIWebView UIScrollView, которые отлично работали для других форматов документов, кроме PDF.

Может ли кто-нибудь помочь выяснить, как отключить Копирование в файлах UIWebView для PDF?

Ответ 1

ОК, поэтому я сам испытываю одну и ту же проблему и, похоже, нахожу решение, даже если оно частично.

Я использую 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 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];

Ответ 2

Это решение работало для меня:

МЕТОД 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 Off, затем снова включите:

-(void)longPressDetected {

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

По-видимому, причина этого в том, что UIWebView захватывает длинные нажатия со своими собственными распознавателями жестов, за исключением каких-либо дополнительных повторных записей жестов, которые вы добавили. Но подклассирование ваших распознавателей жестов и предотвращение их исключения путем возврата "НЕТ" к методу canBePreventedByGestureRecognizer: переопределяет поведение по умолчанию.

Как только вы можете обнаружить длительные нажатия на PDF файлы, переключив UserInteraction Off, а затем снова включите UIWebView, чтобы он выполнил свое поведение по умолчанию, то есть запуск "Копировать/Определить" UIMenu или, если долгое нажатие на ссылку, запуск поп-музыки -up с действиями "Копировать" и "Открыть".

МЕТОД 2 - Поймать UIMenu NSNotification

В качестве альтернативы, если вы просто хотите заблокировать UIMenu "Копировать/Определить" (но не влиять на длинные нажатия), вы можете добавить эту строку (прослушивание UIMenuControllerDidShowMenuNotification) в ViewDidLoad:

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

а затем добавьте этот метод, используя тот же самый метод "Вкл/выкл", как указано выше:

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

Первый метод, взятый из: https://devforums.apple.com/thread/72521?start=25&tstart=0, а второй метод откуда-то на Stack, извините, забыл где. Пожалуйста, укажите, если вы знаете.

Ответ 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 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 {

}

Ответ 4

Если кому-то нужен ответ 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.
}

Ответ 5

Вот модификация ответа 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)

Ответ 6

UILongPressGestureRecognizer находится в UIPDFPageView. Чтобы получить доступ к этому представлению, посмотрите на иерархию представлений в меню "Отладка", в настоящее время вы можете получить доступ к этому виду так, как только вы загрузите PDF в веб-представление:

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

Ответ 7

Ищете решение 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.

Ответ 8

1.ios11 iphone6 ​​Объект-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. Готово!