2

ある種のリッチ テキスト エディターを実装するために、contentEditable div を持つ UIWebView があります。ユーザーがテキストを選択すると、Web ビューに表示される UIMenuController のコピー & カット オプションをトリミングする必要があります。

Web には多くのソリューションがあるようですが、何らかの理由で、私のシナリオには適用されません。

UIWebView をサブクラス化しcanPerformAction:(SEL)action withSender:、コピーとカットを削除する を実装しましたが、ユーザーが「選択」または「すべて選択」を選択すると、新しいメニューが表示され、明らかに、Web ビューはこのアクションと canPerform メソッドをインターセプトしません。は呼び出されていません。

ここに画像の説明を入力

この場合のアクションをトリミングする方法はありますか?

4

1 に答える 1

0

私はあなたのケースに私の別の答えを適応させます。

は、通常はサブクラス化できないではなくcanPerformAction:、内部で実際に呼び出されます。いくつかのランタイム マジックがあれば、それは可能です。UIWebDocumentViewUIWebView

1 つのメソッドを持つクラスを作成します。

@interface _SwizzleHelper : UIView @end

@implementation _SwizzleHelper

-(BOOL)canPerformAction:(SEL)action
{
    //Your logic here
    return NO;
}

@end

アクションを制御したい Web ビューを取得したら、そのスクロール ビューのサブビューを繰り返し、UIWebDocumentViewクラスを取得します。次に、上で作成したクラスのスーパークラスを動的にサブビューのクラス (UIWebDocumentView - ただし、これはプライベート API であるため、事前に言うことはできません) にし、サブビューのクラスをクラスに置き換えます。

#import "objc/runtime.h"    

-(void)__subclassDocumentView
{
    UIView* subview;

    for (UIView* view in self.scrollView.subviews) {
        if([[view.class description] hasPrefix:@"UIWeb"])
            subview = view;
    }

    if(subview == nil) return; //Should not stop here

    NSString* name = [NSString stringWithFormat:@"%@_SwizzleHelper", subview.class.superclass];
    Class newClass = NSClassFromString(name);

    if(newClass == nil)
    {
        newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0);
        if(!newClass) return;

        Method method = class_getInstanceMethod([_SwizzleHelper class], @selector(canPerformAction:));
        class_addMethod(newClass, @selector(canPerformAction:), method_getImplementation(method), method_getTypeEncoding(method));

        objc_registerClassPair(newClass);
    }

    object_setClass(subview, newClass);
}
于 2015-01-16T14:06:12.727 に答える