Menonaktifkan pemilihan pengguna di UIWebView

121

Saya memiliki aplikasi tempat saya memuat konten ke UIWebViewdan menyajikan ini. Saya tidak dapat menonaktifkan interaksi pengguna sepenuhnya karena saya ingin pengguna dapat mengklik link. Saya hanya perlu menonaktifkan pemilihan pengguna. Saya menemukan suatu tempat di Internet yang dapat Anda gunakan:

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

Saya mencoba memasukkan ini sebagai

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

di webViewDidFinishLoad:

Namun, itu tidak berhasil. Saya masih bisa memilih dan menyalin teks di dalam WebView.

Ada ide apa yang mungkin salah?

Pembaruan: Ini sepertinya hanya terjadi mulai dengan iOS 4.3

Engin Kurutepe
sumber

Jawaban:

280

Berikut ini beberapa cara untuk menonaktifkan seleksi:

Tambahkan berikut ini ke dokumen web seluler Anda

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

Muat kode Javascript berikut secara terprogram:

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

Nonaktifkan menu Salin / Tempel pengguna:

- (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];
}
WrightsCS
sumber
1
Perluas UIWebViewmenggunakan kategori.
Deepak Danduprolu
4
Engin, yang pertama berfungsi di Mobile Safari, iOS 4.3.1. Tapi WrightCS lupa menambahkan selektor. Untuk menerapkannya ke semua elemen, gunakan tanda bintang, seperti: * {/ * css di sini * /}
fisherwebdev
1
Menambahkan gaya bekerja dengan sempurna dalam menghapus menu yang muncul saat menekan tautan di dalam aplikasi PhoneGap saya.
spatical
7
canPerformActiontidak menonaktifkan menu Potong, Salin, Tempel. Dan Select, Select All menu. Bagaimana cara mengatasinya? -webkit-touch-calloutdan removeAllRangesmerusak masukan pengguna. Tidak dapat menggunakan semua metode yang disediakan :(
Dmitry
4
Masalah dengan menempatkan gaya tanpa pilih ini dalam *lingkup global adalah ia menghentikan input pengguna dalam formulir web. Saya menemukan saya mendapatkan hasil yang lebih baik dengan menempatkan di dalam bodytag sebagai gantinya.
David Douglas
104

Saya dapat mengonfirmasi bahwa kode berikut berfungsi di 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';"];
}

Juga berfungsi untuk iOS 9 dan lebih baru. Berikut kode swiftnya:

func webViewDidFinishLoad(webView: UIWebView) {
    // Disable user selection
    webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitUserSelect='none'")!
    // Disable callout
    webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitTouchCallout='none'")!
}
TPoschel
sumber
2
Dikonfirmasi di iOS 7! Catatan: Anda dapat mengelompokkan dua panggilan menjadi satu dengan menggabungkan dua string.
Bigood
Di iOS 9.x, panggilan kosong muncul di atas layar setelah ditekan lama, bahkan saat menggunakan di atas.
DwarDoh
bagaimana saya bisa menggunakan kode di atas .. Saya hanya tahu JS; tidak tahu bagaimana saya dapat mengedit kode c obyektif atau mengubah plugin phonegap .. jika ada yang bisa membantu
Lakshay
Bekerja dengan iOS 9 & 10 pria sempurna!
ΩlostA
25

Saya menggunakan teknik ini di aplikasi web untuk Android / iPhone (dipaketkan dengan Trigger.IO) dan menemukan itu hanya akan bekerja dengan sintaks chaining untuk: not () pseudo-class,:

*: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 */

}
Johno Scott
sumber
Saya menggunakan jQuery Mobile dan Phonegap Build dan ini berhasil untuk saya. Saya pertama kali mencoba, *:not(input,textarea) {-webkit-touch-callout: none; -webkit-user-select: none;}tetapi itu tidak berhasil bagi saya. Terima kasih!
Mark Rummel
18

Saya suka solusi WrightsCS tetapi saya akan menggunakan ini sehingga pengguna masih dapat menggunakan tindakan salin, tempel, dan pilih pada input

<style type="text/css">
*:not(input,textarea) {
    -webkit-touch-callout: none;
    -webkit-user-select: none; /* Disable selection/Copy of UIWebView */
}
</style>
pablobart.dll
sumber
2
Jika Anda akan melakukan ini, jangan lupa textarea!
Ryan
9

Saya tidak yakin bagaimana penyiapan dilakukan, tetapi mengapa Anda tidak menghapus pasteBoard saja saat viewWillDisappear dipanggil. Mungkin sesuatu seperti di appDelegate.m Anda:

[UIPasteboard generalPasteboard].string = nil;

ini akan memastikan data apa pun yang mungkin telah disalin pengguna, mereka tidak akan dapat menempelkannya di luar aplikasi.

Selain itu, seperti yang Engin katakan, Anda dapat mengganti metode canPerformSelector di kelas pengontrol yang berisi uiwebview.

Bittu
sumber
1
Ini adalah salah satu solusi terbaik. Ini bisa disetel di - (void) applicationDidEnterBackground: (UIApplication *) application event handler. Dan ini memastikan bahwa tidak ada data yang keluar dari Aplikasi.
Krishnan
@Krishan, apakah Anda 100% yakin itu akan menghentikan tangkapan layar juga?
Norman H
Saya suka solusi ini, tetapi karena itu tetap ada di papan tempel saat aplikasi aktif, aplikasi lain (berbahaya) yang berjalan di utas latar belakang dapat mengakses papan tempel umum saat ada data di dalamnya.
binary_falcon
bukankah ini juga akan menghapus data dari aplikasi? Mungkin mendapatkan data di muncul dan mengaturnya kembali ke menghilang akan bekerja lebih baik
Hamzah Malik
7

Jawaban TPoschel benar tetapi dalam kasus saya urutan penting.

// 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';"];
}
pawelini1
sumber
7

Saya dapat mengonfirmasi bahwa ini pasti akan berhasil untuk Anda.

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

Jika Anda ingin Nonaktifkan hanya tag tombol jangkar gunakan ini.

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

Hasil kerja luar biasa selama satu minggu! Semua jawaban lainnya salah jika Anda ingin menyimpan peristiwa mouse dan input pengguna di banyak halaman.

1) Metode Swizzle (oleh pustaka 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) Tempatkan UIWebView di UIView dan tambahkan kode:

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

Dan yang satu ini:

- (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;
}
Dmitry
sumber
2
Beberapa penjelasan tentang apa yang seharusnya dilakukan ini akan menyenangkan. Secara khusus, saya bingung mengapa isyarat Anda disebut singleTap tetapi membutuhkan dua ketukan.
arlomedia
5
    let longPress:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: nil, action: nil)
    longPress.minimumPressDuration = 0.2
    webView.addGestureRecognizer(longPress)

Cukup tambahkan kode ini ke viewDidLoad () Anda. Pengguna dapat mengklik link tetapi tidak dapat menyalin konten.

Samrat Pramanik
sumber
4

Solusi pertama yang diberikan bekerja dengan sempurna untuk saya ... sampai saya memuat .pdf ke UIWebView saya.

Memuat file .doc bekerja dengan sempurna, tetapi memuat .pdf mengakibatkan baris kode berikut tidak lagi memiliki efek yang diinginkan dan menu salin / tentukan muncul lagi dengan sentuhan panjang oleh pengguna.

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

Setelah pertarungan lain menarik rambut saya menemukan jawaban ini di sini oleh Johnny Rockex dan itu bekerja seperti juara. UIWebView tanpa Copy / Paste saat menampilkan file PDF

Terima kasih banyak kepadanya untuk solusi jenius yang mudah diterapkan ini !!

Skuter
sumber
2

Bagi saya, saya bermaksud mengambil gambar ' NSDatadari UIWebViewoleh LongPressGesture.

Tapi Kaca Pembesar dan Salin / Tempel / Potong selalu muncul sebelum fungsi saya dijalankan.

Dan saya menemukan ini: masukkan deskripsi gambar di sini

Artinya, Kaca Pembesar dan Salin / Tempel / Potong membutuhkan 0,5 detik untuk dijalankan, jadi jika fungsi Anda dapat dijalankan dalam 0,49 detik, SELESAI!

self.longPressPan.minimumPressDuration = 0.3
Kaiyuan Xu
sumber
ini berfungsi untuk saya di iOS 9 + Xcode 7 GM, metode lain yang saya coba hanya berguna di iOS 7 & 8
Kaiyuan Xu
-4

Gunakan fungsi intereksi tampilan web

   webView.userInteractionEnabled = false

Ini bekerja untuk saya

NB: ingat untuk mengaktifkan kembali interaksi saat Anda ingin pengguna dapat berinteraksi dengan tampilan web lagi

Srohr
sumber
1
Selamat datang di stackoverflow. Apakah jawaban benar-benar menambah nilai pertanyaan lama ini? Harap tinjau Bagaimana Menjawab .
dbank
1
Pertimbangkan untuk memperluas jawaban Anda (berikan beberapa contoh kode kecil) untuk meningkatkan nilai jawaban Anda. Selain itu, jawaban yang berisi 'itu berhasil untuk saya' tidak benar-benar menginspirasi kepercayaan - lebih baik menyajikan jawaban apa adanya dan kemudian memecahkan masalah jika seseorang meminta klarifikasi atas jawaban Anda.
Aaron D