Как включить выбор всего в UIWebView в приложении для iPhone?

Я пишу приложение для iPhone, в которое встроен UIWebView. Существуют различные функции, подобные сафари, такие как навигация и т. Д. Одна из задач, которую я ищу, - это предоставить параметр «выбрать все», когда пользователь выбирает фрагмент текста в веб-представлении. В настоящее время я вижу только вариант «копировать». Есть ли простой способ включить пункт меню «выбрать все»? Я, конечно, пытался добавить пункт меню в общий контроллер меню, но это не обязательно реализует исходную функциональность сафари «выбрать все». Любая помощь и указатели будут очень полезны.

Заранее спасибо.


person user299535    schedule 22.01.2011    source источник


Ответы (2)


Короткий ответ: нет, это невозможно.

Вы можете сделать это, создав подкласс UIWebView и переопределив (без добавления чего-либо в контроллер меню самостоятельно):

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

И проверяем, установлен ли селектор selectAll:

Нравится:

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

Это отобразит параметр «Выбрать все» в меню «Удержание». Однако это не поведение по умолчанию для webView, и хотя приложение не выйдет из строя при нажатии кнопки «Выбрать все», нажатие на него ничего не даст.

Вы даже не можете создать метод selectAll, а затем выбрать все в веб-просмотре, потому что метод javascript .select() не работает в Mobile Safari / UIWebView.

person Jonathan.    schedule 12.02.2011
comment
Также следует отметить, что создание подклассов UIWebView запрещено в документации. - person BadPirate; 14.05.2011

Вы можете реализовать поведение selectAll для нередактируемого webView (эквивалент поведения в Apple Mail.app) во время выполнения, используя следующую категорию для UIWebView.

Основная идея состоит в том, чтобы использовать подсказку о том, что UIWebBrowserView, являющееся подвидом UIWebView, является подклассом UIWebDocumentView, который соответствует протоколу UITextInputPrivate, который эквивалентен общедоступному протоколу UITextInput.

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

Конечно, вы можете использовать глобальный метод swizzling для

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

стандартным способом, но это необратимо повлияет на все webView в вашем проекте.

person malex    schedule 29.03.2015