UIWebView Bug: - [UIWebView cut:]:无法识别的选择器发送到实例 [英] UIWebView Bug: -[UIWebView cut:]: unrecognized selector sent to instance
问题描述
在 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屋!