iOS 7的UIWebView键盘问题
我不得不删除这个栏作为这里链接,但对于iOS 7这个代码不起作用。
我们用一些Objective C运行时欺骗来删除这个栏。
我们有一个类有一个方法:
@interface _SwizzleHelper : NSObject @end @implementation _SwizzleHelper -(id)inputAccessoryView { return nil; } @end
一旦我们有一个网页视图,我们要删除栏,我们迭代其滚动视图的子视图,并采取UIWebDocumentView
类。 然后,我们dynamic地将上面创build的类的超类作为子视图的类(UIWebDocumentView – 但是我们不能说这是前期的,因为这是私有API),并将子视图的类replace为我们的类。
#import "objc/runtime.h" -(void)__removeInputAccessoryView { UIView* subview; for (UIView* view in self.scrollView.subviews) { if([[view.class description] hasPrefix:@"UIWeb"]) subview = view; } if(subview == nil) return; NSString* name = [NSString stringWithFormat:@"%@_SwizzleHelper", subview.class.superclass]; Class newClass = NSClassFromString(name); if(newClass == nil) { newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0); if(!newClass) return; Method method = class_getInstanceMethod([_SwizzleHelper class], @selector(inputAccessoryView)); class_addMethod(newClass, @selector(inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method)); objc_registerClassPair(newClass); } object_setClass(subview, newClass); }
在Swift 3.0中相当于上面的那个:
import UIKit import ObjectiveC var swizzledClassMapping = [AnyClass]() extension UIWebView { func noInputAccessoryView() -> UIView? { return nil } public func removeInputAccessoryView() { var subview: AnyObject? for (_, view) in scrollView.subviews.enumerated() { if NSStringFromClass(type(of: view)).hasPrefix("UIWeb") { subview = view } } guard subview != nil else { return } //Guard in case this method is called twice on the same webview. guard !(swizzledClassMapping as NSArray).contains(type(of: subview!)) else { return; } let className = "\type(of: subview!)_SwizzleHelper" var newClass : AnyClass? = NSClassFromString(className) if newClass == nil { newClass = objc_allocateClassPair(type(of: subview!), className, 0) guard newClass != nil else { return; } let method = class_getInstanceMethod(type(of: self), #selector(UIWebView.noInputAccessoryView)) class_addMethod(newClass!, #selector(getter: UIResponder.inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method)) objc_registerClassPair(newClass!) swizzledClassMapping += [newClass!] } object_setClass(subview!, newClass!) } }
我已经根据@bjhomer的博客文章做了一个cocoapod。
您可以replaceinput访问视图,而不是隐藏它。 我希望这会帮助有同样问题的人。
https://github.com/lauracpierre/FA_InputAccessoryViewWebView
你可以在这里findcocoapod页面。
我遇到了这个很棒的解决scheme,但是我也需要重新获得inputAccessoryView。 我加了这个方法:
- (void)__addInputAccessoryView { UIView* subview; for (UIView* view in self.scrollView.subviews) { if([[view.class description] hasSuffix:@"SwizzleHelper"]) subview = view; } if(subview == nil) return; Class newClass = subview.superclass; object_setClass(subview, newClass); }
它似乎按预期工作,没有任何副作用,但我不能摆脱我的裤子着火的感觉。
如果您希望Leo Natan的解决scheme能够使用WKWebView而不是UIWebView,只需将前缀从“UIWeb”更改为“WKContent”即可。
我创build了一个要做到这一点: https : //gist.github.com/kgaidis/5f9a8c7063b687cc3946fad6379c1a66
这是一个UIWebView
类别,您只需更改customInputAccessoryView
属性即可:
@interface UIWebView (CustomInputAccessoryView) @property (strong, nonatomic) UIView *customInputAccessoryView; @end
您可以将其设置nil
来删除它,或者您可以设置一个新的视图来改变它。
请记住,这也使用私人API,所以使用风险自负,但似乎很多应用程序做类似的事情。