Отключение выбора пользователя в UIWebView

У меня есть приложение, в котором я загружаю контент в UIWebView и представляю его. Я не могу полностью отключить взаимодействие пользователя, потому что я хочу, чтобы пользователь мог нажимать ссылки. Мне просто нужно отключить выбор пользователя. Я нашел где-то в Интернетах, которые вы можете использовать:

document.body.style.webkitUserSelect='none';

Я попытался вставить это как

[self.contentView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitUserSelect='none';"]; 

в webViewDidFinishLoad:

Однако это не сработает. Я все еще могу выбирать и копировать текст внутри WebView.

Любые идеи, что может быть неправильным?

Обновление: похоже, это происходит, начиная с iOS 4.3

Ответ 1

Вот несколько способов отключить выбор:

Добавьте в свои мобильные веб-документы следующие документы

<style type="text/css">
* {
    -webkit-touch-callout: none;
    -webkit-user-select: none; /* Disable selection/copy in UIWebView */
}
</style>

Программно загрузите следующий код Javascript:

NSString * jsCallBack = @"window.getSelection().removeAllRanges();";    
[webView stringByEvaluatingJavaScriptFromString:jsCallBack];

Отключите меню пользователя "Копировать/Вставить":

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender 
{    
    if (action == @selector(copy:) ||
        action == @selector(paste:)||
        action == @selector(cut:)) 
    {
        return _copyCutAndPasteEnabled;
    }
    return [super canPerformAction:action withSender:sender];
}

Ответ 2

Я могу подтвердить, что следующий код работает в iOS 5.0 - 8.0.

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    // Disable user selection
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
    // Disable callout
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}

Также работает для iOS 9. Здесь быстрый код:

func webViewDidFinishLoad(webView: UIWebView) {
    // Disable user selection
    webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitUserSelect='none'")!
    // Disable callout
    webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitTouchCallout='none'")!
}

Ответ 3

Я использую эту технику в веб-приложении для Android/iPhone (в комплекте с Trigger.IO) и обнаружил, что он будет работать только с синтаксисом цепочки для: not() псевдокласса:

*:not(input):not(textarea) {
-webkit-user-select: none; /* disable selection/Copy of UIWebView */
    -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */

}

Ответ 4

Мне нравится решение WrightsCS, но я буду использовать его, чтобы пользователи все еще могли использовать копии, вставлять и выбирать действия на входах

<style type="text/css">
*:not(input,textarea) {
    -webkit-touch-callout: none;
    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */
}
</style>

Ответ 5

Я не уверен, как выполняется настройка, но почему бы вам не просто очистить панель paste при вызове viewWillDisappear. Может быть, что-то вроде вашего appDelegate.m:

[UIPasteboard generalPasteboard].string = nil;

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

Кроме того, как сказал Энгин, вы можете переопределить метод canPerformSelector в классе контроллера, который содержит uiwebview.

Ответ 6

Ответ TPoschel - это corrent, но в моем случае порядок был важен.

// this works - locks selection and callout
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}

// this doesn't work - locks only callout
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
}

Ответ 7

Результат большой работы в течение одной недели! Все остальные ответы неверны, если вы хотите сохранить события мыши и пользовательский ввод на многих страницах.

1) Метод Swizzle (через rentzsch/jrswizzle библиотека):

[NSClassFromString(@"UIWebDocumentView") jr_swizzleMethod:@selector(canPerformAction:withSender:) withMethod:@selector(myCanPerformAction:withSender:) error:nil];

NSObject + myCanPerformAction.h:

@interface NSObject (myCanPerformAction)

- (BOOL)myCanPerformAction:(SEL)action withSender:(id)sender;

@end

NSObject + myCanPerformAction.m:

#import "NSObject+myCanPerformAction.h"

@implementation NSObject (myCanPerformAction)

- (BOOL)myCanPerformAction:(SEL)action withSender:(id)sender {
    if (action == @selector(copy:)) {
        return [self myCanPerformAction:action withSender:sender];
    }
    if (action == @selector(paste:)) {
        return [self myCanPerformAction:action withSender:sender];
    }
    return NO;
}

@end

2) Поместите UIWebView на UIView и добавьте код:

    UITapGestureRecognizer* singleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];
    singleTap.numberOfTapsRequired = 2;
    singleTap.numberOfTouchesRequired = 1;
    singleTap.delegate = self;
    [self.view addGestureRecognizer:singleTap];

И этот:

- (void)handleSingleTap:(UIGestureRecognizer*)gestureRecognizer {
    return;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    if ([otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        UITapGestureRecognizer *gesture = (UITapGestureRecognizer *)otherGestureRecognizer;
        if (gesture.numberOfTapsRequired == 2) {
            [otherGestureRecognizer.view removeGestureRecognizer:otherGestureRecognizer];
        }
    }
    return YES;
}

Ответ 8

Я могу подтвердить, что это определенно сработает для вас.

<style type="text/css">
  *:not(input):not(textarea) {
   -webkit-user-select: none; /* disable selection/Copy of UIWebView */
   -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
   }       
</style>

Если вы хотите отключить тег кнопки привязки только для использования, используйте это.

    a {-webkit-user-select: none; /* disable selection/Copy of UIWebView */
   -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
     }

Ответ 9

Первое заданное решение отлично сработало для меня... пока я не загрузил .pdf в свой UIWebView.

Загрузка файла .doc работала отлично, но загрузка .pdf привела к тому, что следующая строка кода больше не имела желаемого эффекта, а меню копирования/определения появилось снова при длительном касании пользователя.

    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];

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

Огромное спасибо ему за это простое решение, гениальное решение!

Ответ 10

    let longPress:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: nil, action: nil)
    longPress.minimumPressDuration = 0.2
    webView.addGestureRecognizer(longPress)

Просто добавьте этот код в свой viewDidLoad(). Пользователь может нажать ссылку, но не может скопировать содержимое.

Ответ 11

Для меня я намеревался получить изображения NSData от UIWebView на LongPressGesture.

Но лупа и копирование/вставка/вырез всегда выполняются до выполнения моей функции.

И я нашел это:  введите описание изображения здесь

Это означает, что Лупа и Копировать/Вставить/Вырезать нужно выполнить 0,5 с, поэтому, если ваша функция может быть выполнена в 0,49, DONE!

self.longPressPan.minimumPressDuration = 0.3

Ответ 12

Использовать функцию интертекста просмотра

   webView.userInteractionEnabled = false

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

PS: не забудьте включить взаимодействие обратно, когда вы хотите, чтобы пользователь снова мог взаимодействовать с веб-просмотром.