How to enable "select all" in a UIWebView in an iPhone app?

I am writing an iPhone application that includes a UIWebView. There are various safari features such as navigation, etc. One of the tasks I'm looking for is to present the “select all” option when a user selects a portion of the text in a web view. Currently, I only see the copy option. Is there an easy way to enable “select all”? Of course, I tried to add a menu item to the general menu controller, but this does not necessarily implement the initial “select all” safari functionality. Any help and pointers would be very helpful.

Thanks in advance.

+4
source share
2 answers

The short answer is no, this is not possible.

You can do this by subclassing the UIWebView and overriding it (without adding any changes to the menu controller yourself):

-(BOOL) canPerformAction:(SEL)action withSender:(id)sender 

And check that selectAll: selector selectAll:

Like this:

 -(BOOL) canPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(selectAll:)) { return YES; } else { return [super canPerformAction:action withSender:sender]; } } 

The “Select All” option appears in the hold window. However, this is not the default behavior for webView, and until the application crashes when you click the Select All button, clicking on it will simply do nothing.

You cannot even create the selectAll method and then select everything in webview because the javascript .select() method does not work in Mobile Safari / UIWebView.

+2
source

You can implement the selectAll behavior for a selectAll -editable webView (equivalent to the behavior in Apple Mail.app) at run time using the following category for UIWebView .

The basic idea is to use the hint that UIWebBrowserView is a subzone. UIWebView is a subclass of UIWebDocumentView that conforms to the UITextInputPrivate protocol, which is equivalent to the public UITextInput protocol

 // UIWebView+SelectAll.h // Created by Alexey Matveev on 28.03.15. // Copyright (c) 2015 Alexey Matveev. All rights reserved. @interface UIWebView (SelectAll) + (void)setEnableSelectAll:(BOOL)enabled; @end #import "UIWebView+SelectAll.h" #import <objc/runtime.h> /* UIWebDocumentView is the superclass for UIWebBrowserView. UIWebDocumentView conforms UITextInputPrivate protocol which is identival to UITextInput */ static IMP canPerformActionWithSenderImp; @implementation UIWebView (SelectAll) @dynamic enableSelectAll; - (BOOL)customCanPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(selectAll:)) { return ! self.isSelectedAll; } else { BOOL(*imp)(id, SEL, SEL, id) = (BOOL(*)(id, SEL, SEL, id))canPerformActionWithSenderImp; return imp(self, @selector(canPerformAction:withSender:), action, sender); } } - (void)selectAll:(id)sender { [self.browserView selectAll:sender]; } - (UIView<UITextInput> *)browserView { UIView *browserView; for (UIView *subview in self.scrollView.subviews) { if ([subview isKindOfClass:NSClassFromString(@"UIWebBrowserView")]) { browserView = subview; break; } } return (UIView<UITextInput> *)browserView; } - (BOOL)isSelectedAll { UITextRange *currentRange = self.browserView.selectedTextRange; if ([self.browserView comparePosition:currentRange.start toPosition:self.browserView.beginningOfDocument] == NSOrderedSame) { if ([self.browserView comparePosition:currentRange.end toPosition:self.browserView.endOfDocument] == NSOrderedSame) { return YES; } } return NO; } + (void)setEnableSelectAll:(BOOL)enabled { SEL canPerformActionSelector = @selector(canPerformAction:withSender:); if (!canPerformActionWithSenderImp) { canPerformActionWithSenderImp = [self instanceMethodForSelector:canPerformActionSelector]; } IMP newCanPerformActionWithSenderImp = enabled ? [self instanceMethodForSelector:@selector(customCanPerformAction:withSender:)] : canPerformActionWithSenderImp; Method canPerformActionMethod = class_getInstanceMethod([self class], canPerformActionSelector); class_replaceMethod([self class], canPerformActionSelector, newCanPerformActionWithSenderImp, method_getTypeEncoding(canPerformActionMethod)); } @end 

Of course you can use the global swizzling method to

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

in a standard way, but it will affect all web projects in your project irreversibly.

0
source

Source: https://habr.com/ru/post/1336558/


All Articles