UIWebView Bug:-[UIWebView cut:]:无法识别的选择器发送到实例

2024-05-18

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

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

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

我想这一定是一个UIWebView错误,有什么想法吗?

为了完整起见,以下是我的网络视图的内容,

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

向 Apple 提交错误报告:15894403

2019/05/30 更新:iOS 12.0 (16E226) 中仍然存在错误


这是苹果的一个错误。问题是cut:动作在响应者链中发送错误,最终被发送到UIWebView实例而不是内部UIWebDocumentView,它实现了该方法。

在 Apple 修复该错误之前,让我们享受一下 Objective C 运行时的乐趣吧。

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

@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

在故事板中使用这个子类。

玩得开心。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIWebView Bug:-[UIWebView cut:]:无法识别的选择器发送到实例 的相关文章

随机推荐