UIWebView Bug: - [UIWebView cut:]:无法识别的选择器发送到实例 [英] UIWebView Bug: -[UIWebView cut:]: unrecognized selector sent to instance

查看:118
本文介绍了UIWebView Bug: - [UIWebView cut:]:无法识别的选择器发送到实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UIWebView 中,如果包含文本的输入元素具有焦点,并且按下按钮导致输入失去焦点,则随后双击输入重新获得焦点并从显示的弹出栏中选择剪切(或复制或粘贴)会导致 UIWebView 因错误而崩溃:

In the UIWebView, if an input element containing text has focus, and a button is pressed that causes the input to lose focus, then subsequently double-tapping on the input to regain focus and selecting Cut (or Copy or Paste) from the popup bar that appears causes the UIWebView to crash with the error:

-[UIWebView cut:]: unrecognized selector sent to instance 0x10900ca60

演示项目: https://github.com/guarani/WebViewDoubleTapTestTests.git

我认为这必须是 UIWebView 错误,任何想法?

I think this must be a UIWebView bug, any ideas?

为了完整性,以下是我的网页视图的内容,

For completeness, here are the contents of my web view,

<html>
    <head>
    </head>
    <body>
        <br><br>
        <input type="text">
        <input type="button">
    </body>
</html>

在Apple提交的错误报告:15894403

Filed a Bug Report at Apple: 15894403

更新2014/10/15:iOS 8.0.2中仍存在错误(12A405)

推荐答案

<这是一个Apple bug。问题是 cut:操作在响应程序链中发送错误,最终被发送到 UIWebView 实例而不是实现该方法的内部 UIWebDocumentView

This is an Apple bug. The problem is the cut: action is sent incorrectly in the responder chain, and ends up being sent to the UIWebView instance instead of the internal UIWebDocumentView, which implements the method.

直到Apple修复了这个bug,让我们玩得开心Objective C运行时。

Until Apple fixes the bug, let's have some fun with the Objective C runtime.

在这里,我将 UIWebView 子类化,目的是支持所有 UIResponderStandardEditActions 方法,将它们转发到正确的内部实例。

Here, I subclass UIWebView with the purpose of supporting all UIResponderStandardEditActions methods, by forwarding them to the correct internal instance.

@import ObjectiveC;    

@interface CutCopyPasteFixedWebView : UIWebView @end

@implementation CutCopyPasteFixedWebView

- (UIView*)_internalView
{
    UIView* internalView = objc_getAssociatedObject(self, "__internal_view_key");

    if(internalView == nil && self.subviews.count > 0)
    {
        for (UIView* view in self.scrollView.subviews) {
            if([view.class.description hasPrefix:@"UIWeb"])
            {
                internalView = view;

                objc_setAssociatedObject(self, "__internal_view_key", view, OBJC_ASSOCIATION_ASSIGN);

                break;
            }
        }
    }

    return internalView;
}

void webView_implement_UIResponderStandardEditActions(id self, SEL selector, id param)
{
    void (*method)(id, SEL, id) = (void(*)(id, SEL, id))[[self _internalView] methodForSelector:selector];

    //Call internal implementation.
    method([self _internalView], selector, param);
}

- (void)_prepareForNoCrashes
{
    NSArray* selectors = @[@"cut:", @"copy:", @"paste:", @"select:", @"selectAll:", @"delete:", @"makeTextWritingDirectionLeftToRight:", @"makeTextWritingDirectionRightToLeft:", @"toggleBoldface:", @"toggleItalics:", @"toggleUnderline:", @"increaseSize:", @"decreaseSize:"];

    for (NSString* selName in selectors)
    {
        SEL selector = NSSelectorFromString(selName);

        //This is safe, the method will fail if there is already an implementation.
        class_addMethod(self.class, selector, (IMP)webView_implement_UIResponderStandardEditActions, "");
    }
}

- (void)awakeFromNib
{
    [self _prepareForNoCrashes];

    [super awakeFromNib];
}

@end

在故事板中使用此子类。

Use this subclass in your storyboard.

玩得开心。

这篇关于UIWebView Bug: - [UIWebView cut:]:无法识别的选择器发送到实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆