我必须移除这个栏位,就像链接中所示,但对于iOS 7来说,这段代码无效。
@interface _SwizzleHelper : NSObject @end
@implementation _SwizzleHelper
-(id)inputAccessoryView
{
return nil;
}
@end
一旦我们有了一个想要从中移除栏的 Web 视图,我们会迭代其滚动视图的子视图并获取 UIWebDocumentView
类。然后,我们动态地将上面创建的类的超类设置为子视图的类(UIWebDocumentView - 但我们不能直接说这是私有 API),并将子视图的类替换为我们的类。
#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!)
}
}
https://github.com/lauracpierre/FA_InputAccessoryViewWebView
你可以在这里找到cocoapod页面这里。我遇到了这个很棒的解决方案,但是我也需要获取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的解决方案与WKWebView一起工作而不是UIWebView,只需将前缀从“UIWeb”更改为“WKContent”即可。
UIWebView
类别,你所要做的就是改变customInputAccessoryView
属性:@interface UIWebView (CustomInputAccessoryView)
@property (strong, nonatomic) UIView *customInputAccessoryView;
@end
您可以将其设置为 nil
以删除它,也可以在其上设置一个新视图来更改它。
请注意,这也使用了私有API,因此请自行承担风险,但似乎很多应用程序仍然会做类似的事情。
subview
是如何定义的?我使用了NSObject *subview = [[webView scrollView] subviews][0];
(实际上是一个UIWebBrowserView
对象,也是 scrollView 的唯一子视图),但是 Objective-C 在运行时崩溃并显示:[UIWebDocumentView_SwizzleHelper autoFillDelegate]: unrecognized selector sent to instance 0xa8cba00
。 - LarryUIWebView
子类中。同时你需要在文件顶部#import "objc/runtime.h"
. - Larry