web-dev-qa-db-ja.com

UIWebViewでのユーザー選択の無効化

コンテンツをUIWebViewに読み込んで提示するアプリがあります。ユーザーがリンクをクリックできるようにするため、ユーザーの操作を完全に無効にすることはできません。ユーザー選択を無効にするだけです。私はあなたが使用できるインターネットのどこかを見つけました:

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

これを挿入してみました

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

webViewDidFinishLoad:

ただし、機能しません。 WebView内でテキストを選択してコピーできます。

何が間違っているのでしょうか?

更新:これはiOS 4.3以降でのみ発生するようです

118
Engin Kurutepe

選択を無効にするいくつかの方法を次に示します。

以下をモバイルWebドキュメントに追加します

<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];
}
274
WrightsCS

次のコードが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以降でも動作します。 Swiftコードは次のとおりです。

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

私はAndroid/iPhone(Trigger.IOにパッケージ化)用のWebアプリでこの手法を使用しており、: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 */

}
24
Johno Scott

私はWrightsCSソリューションが好きですが、ユーザーがコピー、貼り付け、入力のアクションを選択できるようにこれを使用します

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

セットアップがどのように行われるかはわかりませんが、viewWillDisappearが呼び出されたときにpasteBoardをクリアしないでください。たぶんあなたのappDelegate.mのようなもの:

[UIPasteboard generalPasteboard].string = nil;

これにより、ユーザーがコピーしたデータがすべて確実になり、アプリの外部に貼り付けることができなくなります。

また、Enginが言ったように、uiwebviewを含むコントローラークラスのcanPerformSelectorメソッドをオーバーライドできます。

9
Bittu

TPoschelの答えは正しいですが、私の場合は順序が重要でした。

// 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
pawelini1

これは間違いなくあなたのために働くことを確認できます。

<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 */
     }
7
Narsingh Tomar

1週間のすばらしい仕事の結果!マウスイベントとユーザー入力を多くのページに保存する場合、他のすべての回答は正しくありません。

1)Swizzleメソッド(by rentzsch/jrswizzle library):

[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)UIViewにUIWebViewを配置し、コードを追加します。

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

与えられた最初の解決策は、.pdfをUIWebViewにロードするまで完璧に機能しました。

.docファイルのロードは完全に機能しましたが、.pdfのロードにより、次のコード行では目的の効果が得られなくなり、ユーザーが長押しするとコピー/定義メニューが再びポップアップしました。

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

もう一度髪を引っ張った後、私はここでジョニー・ロケックスによるこの答えを見つけました、そしてそれはチャンピオンのように働きました。 PDFファイルを表示するときにコピー/貼り付けなしのUIWebView

この実装が簡単な天才的なソリューションに感謝します!!

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

このコードをviewDidLoad()に追加するだけです。ユーザーはリンクをクリックできますが、コンテンツをコピーできません。

3
Samrat Pramanik

私にとっては、NSDataからUIWebViewから画像のLongPressGestureを取得するつもりでした。

しかし、拡大鏡とコピー/貼り付け/切り取りは、常にfuncが実行される前に発生します。

そして、私はこれを見つけました: enter image description here

つまり、拡大鏡とコピー/貼り付け/切り取りの実行には0.5秒が必要なので、0.49秒でfuncを実行できる場合は、完了です!

self.longPressPan.minimumPressDuration = 0.3
2
Kaiyuan Xu