J'ai une application où je charge du contenu sur un UIWebView
et le présente. Je ne peux pas désactiver complètement l'interaction de l'utilisateur, car je souhaite que l'utilisateur puisse cliquer sur les liens. Je dois juste désactiver la sélection de l'utilisateur. J'ai trouvé quelque part dans les internets que vous pouvez utiliser:
document.body.style.webkitUserSelect='none';
J'ai essayé d'insérer ceci comme
[self.contentView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitUserSelect='none';"];
dans webViewDidFinishLoad:
Cependant, ça ne marche pas. Je suis toujours capable de sélectionner et de copier du texte dans WebView.
Des idées sur ce qui pourrait mal tourner?
Mise à jour: Cela ne semble se produire qu'à partir de iOS 4.3
Voici quelques façons de désactiver la sélection:
<style type="text/css">
* {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/copy in UIWebView */
}
</style>
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];
}
Je peux confirmer que le code suivant fonctionne dans 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';"];
}
Fonctionne également pour iOS 9 et versions ultérieures. Voici le code Swift:
func webViewDidFinishLoad(webView: UIWebView) {
// Disable user selection
webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitUserSelect='none'")!
// Disable callout
webView.stringByEvaluatingJavaScriptFromString("document.documentElement.style.webkitTouchCallout='none'")!
}
J'utilise cette technique dans une application Web pour Android/iPhone (fourni avec Trigger.IO) et je ne trouve que cela fonctionnerait qu'avec la syntaxe d'enchaînement de la pseudo-classe: 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 */
}
J'aime la solution WrightsCS mais je vais l'utiliser pour que les utilisateurs puissent toujours utiliser les actions copier, coller et sélectionner les entrées
<style type="text/css">
*:not(input,textarea) {
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/Copy of UIWebView */
}
</style>
Je ne suis pas sûr de savoir comment la configuration est faite, mais pourquoi ne pas simplement effacer le pasteBoard lorsque viewWillDisappear est appelé. Peut-être que quelque chose comme dans votre appDelegate.m:
[UIPasteboard generalPasteboard].string = nil;
cela garantira que tout ce que l'utilisateur de données aurait pu copier, il ne pourra pas le coller en dehors de l'application.
En outre, comme Engin l'a dit, vous pouvez remplacer la méthode canPerformSelector dans la classe de contrôleur qui contient uiwebview.
La réponse de TPoschel est correcte mais dans mon cas, l'ordre était important.
// 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';"];
}
Je peux confirmer que cela fonctionnera définitivement pour vous.
<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>
Si vous voulez désactiver uniquement la balise du bouton d'ancrage, utilisez ceci.
a {-webkit-user-select: none; /* disable selection/Copy of UIWebView */
-webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */
}
1) Méthode Swizzle (par rentzsch/jrswizzle bibliothèque):
[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) Placez UIWebView sur UIView et ajoutez un code:
UITapGestureRecognizer* singleTap = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)] autorelease];
singleTap.numberOfTapsRequired = 2;
singleTap.numberOfTouchesRequired = 1;
singleTap.delegate = self;
[self.view addGestureRecognizer:singleTap];
Et celui-là:
- (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;
}
La première solution proposée a parfaitement fonctionné pour moi ... jusqu'à ce que je charge un fichier .pdf dans mon UIWebView.
Le chargement d'un fichier .doc fonctionnait parfaitement, mais le chargement d'un fichier .pdf avait pour résultat que la ligne de code suivante n'avait plus l'effet souhaité et que le menu de copie/définition réapparaissait de manière prolongée par l'utilisateur.
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
Après une nouvelle crise de cheveux, j'ai trouvé cette réponse de Johnny Rockex et cela a fonctionné comme un champion. IWebView sans copier/coller lors de l'affichage de PDF
Merci beaucoup à lui pour cette solution facile à mettre en œuvre, géniale !!
let longPress:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: nil, action: nil)
longPress.minimumPressDuration = 0.2
webView.addGestureRecognizer(longPress)
Ajoutez simplement ce code à votre viewDidLoad (). L'utilisateur peut cliquer sur le lien mais ne peut pas copier le contenu.
Pour moi, j'avais l'intention de récupérer les images 'NSData
de UIWebView
de LongPressGesture
.
Mais la Loupe et Copier/Coller/Couper se produisent toujours avant que ma fonction ne soit exécutée.
Cela signifie que la Loupe et Copier/Coller/Couper a besoin de 0.5s pour s'exécuter, donc si votre fonction peut être exécutée en 0.49s, FAIT!
self.longPressPan.minimumPressDuration = 0.3