【问题标题】:UIWebView: Disable copy/cut options for a rich text editorUIWebView:禁用富文本编辑器的复制/剪切选项
【发布时间】:2013-08-15 17:45:49
【问题描述】:

为了实现某种富文本编辑器,我有一个带有 contentEditable div 的 UIWebView。一旦用户选择任何一段文本,我需要修剪出现在 Web 视图中的 UIMenuController 中的复制和剪切选项。

网络上似乎有很多解决方案,但由于某种原因,没有一个适用于我的场景。

我已经将 UIWebView 子类化并实现了canPerformAction:(SEL)action withSender: 以删除复制和剪切,但是一旦用户选择“选择”或“全选”,就会出现一个新菜单,并且显然,网络视图不会拦截这个动作和 canPerform 方法没有被调用。

有没有办法为这种情况修剪动作?

【问题讨论】:

    标签: iphone ios ipad uiwebview rich-text-editor


    【解决方案1】:

    我会根据你的情况调整another answer of mine

    canPerformAction: 实际上是在内部 UIWebDocumentView 上调用的,而不是 UIWebView,您通常不能对其进行子类化。借助一些运行时魔法,这是可能的。

    我们创建一个有一个方法的类:

    @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);
    }
    

    【讨论】:

    • 有趣的方法。我想知道您为什么要动态创建UIWebDocumentView 的新子类。直接调配-canPerformAction:UIWebDocumentView 不是更容易吗?
    • 这是可能的,但这更容易实现。更容易调用超实现,更容易覆盖方法,无论超类链中哪个类实现它。如果您要直接调配方法,则需要找出哪个超类是第一个实现它的超类,然后调配——如果在其他地方使用该类可能会出现问题。
    • 你能分享这个Demo吗?它仍然无法在我的代码中运行。
    猜你喜欢
    • 2013-02-11
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    相关资源
    最近更新 更多