在Swift中删除WKWebView Accesory栏

时间:2015-11-22 10:47:15

标签: ios objective-c swift

我现在正试着将this转换成Swift而没有太多背景知识。

这是我到目前为止所得到的...而且我一直在寻找谷歌并不知道要搜索什么才能更具体。你能否详细说明我做错了什么?感谢

更新

我已经找到了objective-c标签,因此更多与此主题相关的人可能会看到它并希望得到答案。

enter image description here

4 个答案:

答案 0 :(得分:10)

Michael Dautermann回答说得对,但为了隐藏附件栏,你需要使用_NoInputAccessoryView类的inputAccessoryView()来调用UIView类的方法inputAccessoryView()。我刚刚在代码中添加了几行额外的行来完成方法调配的工作。

首先,你需要一个假的类与

交换
final class FauxBarHelper: NSObject {
    var inputAccessoryView: AnyObject? { return nil }
}

然后在控制器类中创建此方法

/// Removes the keyboard accessory view from the web view
/// Source: http://stackoverflow.com/a/32620344/308315 / http://stackoverflow.com/a/33939584/308315
func _removeInputAccessoryView(webView: UIWebView) {
    var targetView: UIView? = nil

    for view in webView.scrollView.subviews {
        if String(describing: type(of: view)).hasPrefix("WKContent") {
            targetView = view
        }
    }

    guard let target = targetView else { return }

    let noInputAccessoryViewClassName = "\(target.superclass!)_NoInputAccessoryView"
    var newClass: AnyClass? = NSClassFromString(noInputAccessoryViewClassName)
    if newClass == nil {
        let targetClass: AnyClass = object_getClass(target)
        newClass = objc_allocateClassPair(targetClass, noInputAccessoryViewClassName.cString(using: String.Encoding.ascii)!, 0)
    }

    let originalMethod = class_getInstanceMethod(FauxBarHelper.self, #selector(getter: FauxBarHelper.inputAccessoryView))
    class_addMethod(newClass!.self, #selector(getter: FauxBarHelper.inputAccessoryView), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
    object_setClass(target, newClass)
}

HTH;)

答案 1 :(得分:6)

对于仍在寻找的人,WebKit团队更新了WKWebView(iOS 13+),以便您可以对其进行子类化以删除/更新输入的附件视图:

https://trac.webkit.org/changeset/246229/webkit#file1

在Swift中,我将其子类化,并返回nil。按预期工作。希望对您有所帮助。

仅供参考:我检查了文档,并且子类WKWebView中没有提及 not ,因此允许子类化。

import WebKit

class RichEditorWebView: WKWebView {

    var accessoryView: UIView?

    override var inputAccessoryView: UIView? {
        // remove/replace the default accessory view
        return accessoryView
    }

}

您可以在这里找到它的有效版本:https://github.com/cbess/RichEditorView/commits/master

答案 2 :(得分:5)

这是一个稍微安全(没有不安全的unwraps)版本,适用于Swift 4和(至少)iOS 9 trough 12。

fileprivate final class InputAccessoryHackHelper: NSObject {
    @objc var inputAccessoryView: AnyObject? { return nil }
}

extension WKWebView {
    func hack_removeInputAccessory() {
        guard let target = scrollView.subviews.first(where: {
            String(describing: type(of: $0)).hasPrefix("WKContent")
        }), let superclass = target.superclass else {
            return
        }

        let noInputAccessoryViewClassName = "\(superclass)_NoInputAccessoryView"
        var newClass: AnyClass? = NSClassFromString(noInputAccessoryViewClassName)

        if newClass == nil, let targetClass = object_getClass(target), let classNameCString = noInputAccessoryViewClassName.cString(using: .ascii) {
            newClass = objc_allocateClassPair(targetClass, classNameCString, 0)

            if let newClass = newClass {
                objc_registerClassPair(newClass)
            }
        }

        guard let noInputAccessoryClass = newClass, let originalMethod = class_getInstanceMethod(InputAccessoryHackHelper.self, #selector(getter: InputAccessoryHackHelper.inputAccessoryView)) else {
            return
        }
        class_addMethod(noInputAccessoryClass.self, #selector(getter: InputAccessoryHackHelper.inputAccessoryView), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        object_setClass(target, noInputAccessoryClass)
    }
}

答案 3 :(得分:3)

此代码段可以帮助您解决问题:

class _NoInputAccessoryView: NSObject {

    func removeInputAccessoryViewFromWKWebView(webView: WKWebView) {
        // make sure to make UIView an optional here...
        var targetView: UIView? = nil
        for view in webView.scrollView.subviews {
            if String(view.dynamicType).hasPrefix("WKContent") {
                targetView = view
            }
        }

        // only optionals can be nil
        if targetView == nil {
            return
        }

        let noInputAccessoryViewClassName = "\(targetView!.superclass)_NoInputAccessoryView"
        var newClass : AnyObject? = NSClassFromString(noInputAccessoryViewClassName)
        if newClass == nil {
            let uiViewClass : AnyClass = object_getClass(targetView!)
            newClass = objc_allocateClassPair(uiViewClass, noInputAccessoryViewClassName.cStringUsingEncoding(NSASCIIStringEncoding)!, 0)
        }
    } 

您还可以使用“String(view.dynamicType)”获取您正在查看的对象的班级名称as I noticed via this answer as I was researching the way to solve your problem

在Objective-C和Swift中同样使用hasPrefix非常hacky,也许可以找到更好的隐藏键盘的方法来生成代码?