How to enable “select all” in UIWebView in an IPhone App?

狂风中的少年 提交于 2019-12-04 03:54:55

问题


I am writing an IPhone application which embeds a UIWebView. There are various safari like features like navigation, etc. One of the tasks I am looking for is to present a "select all" option when the user selects on a piece of text on the web view. Currently, I only see a "copy" option. Is there an easy way to enable the "select all" menu item? I have ofcourse tried adding a menu item to the shared menu controller but that doesn't necessarily implement the original safari "select all" functionality. Any help and pointers will be very useful.

Thanks in advance.


回答1:


The short answer is no, this is not possible.

You could do this by subclassing UIWebView and overriding (without adding anythings to the menu controller yourself):

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

And checking if the selector is selectAll:

Like this:

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

This will show the Select All option on the Hold Menu. However this isn't default behaviour of a webView, and while the app won't crash when you press Select All, pressing it will just do nothing.

You can't even create a selectAll method, and then select everything in webview, because the javascript method .select() doesn't work on Mobile Safari/UIWebView.




回答2:


You can implement selectAll behavior for non-editable webView (equivalent to behavior at Apple's Mail.app) at runtime using the following category for UIWebView.

The main idea is to use the hint that UIWebBrowserView being the subview of UIWebView is the subclass of UIWebDocumentView which conforms to UITextInputPrivate protocol which is equivalent to 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 global method swizzling for

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

in the standard way but it will affect all webViews in your project irreversably.



来源:https://stackoverflow.com/questions/4766975/how-to-enable-select-all-in-uiwebview-in-an-iphone-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!