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.
malex source share