这是苹果的一个错误。问题是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
在故事板中使用这个子类。
玩得开心。