在UIWebView中,如果包含文本的输入元素具有焦点,并且按下一个导致输入失焦的按钮,则随后双击输入以重新获得焦点,然后从弹出式栏中选择“剪切(或复制或粘贴)”这样会导致UIWebView崩溃与错误:
-[UIWebView cut:]: unrecognized selector sent to instance 0x10900ca60
演示项目:https://github.com/guarani/WebViewDoubleTapTestTests.git
我觉得这一定是UIWebView的bug,有什么想法吗?
为了完整,这里是我的网页视图的内容,
<html> <head> </head> <body> <br><br> <input type="text"> <input type="button"> </body> </html>
更新2014/10/15:Bug仍然存在于iOS 8.0.2(12A405)
解决方法
这是一个苹果bug.问题是剪切:操作在响应者链中发送不正确,最终被发送到UIWebView实例,而不是实现该方法的内部UIWebDocumentView.
直到Apple修复了这个bug,让我们来看看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,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,(IMP)webView_implement_UIResponderStandardEditActions,""); } } - (void)awakeFromNib { [self _prepareForNoCrashes]; [super awakeFromNib]; } @end
在你的故事板中使用这个子类.
玩的开心.