如何编辑从 WKWebView 显示的键盘附件视图?

Posted

技术标签:

【中文标题】如何编辑从 WKWebView 显示的键盘附件视图?【英文标题】:How to edit accessory view of keyboard shown from WKWebView? 【发布时间】:2018-08-14 08:29:56 【问题描述】:

我在我的 Swift 应用程序中使用 WKWebView 来呈现一些文本字段。

我设置了一些外观属性来匹配特定的设计,在这种情况下,它的背景必须是蓝色的。 但是当WKWebView触发键盘时,它对外观属性做了一些事情,并以我的颜色的淡光外观显示键盘工具栏,你知道为什么吗?

UIToolBar 上唯一有效的外观操作是这个:

    UIToolbar.appearance().backgroundColor = .blue

这是我的问题:

这是我的目标:

【问题讨论】:

***.com/questions/48978134/… Modifying keyboard toolbar / accessory view with WKWebView的可能重复 感谢您的cmets,我会检查他们,如果它与结果相关,我会将您的评论标记为答案。如果重复,我将删除问题。 谢谢,引用的问题很有趣,但不影响我的问题。所以我还在寻找如何解决这个问题。 有人找到解决方案了吗? 【参考方案1】:

找到了一种方法,最终调配了 UIToolbars。希望一切都在那里,但你会有一个想法。斯威夫特 4:

class YourController: UIViewController 

    @IBOutlet weak var webView: PWebView!
    var toolbar : UIToolbar?

    func viewDidLoad() 
        webView.addInputAccessoryView(toolbar: self.getToolbar(height: 44))
    

    func getToolbar(height: Int) -> UIToolbar? 
        let toolBar = UIToolbar()
        toolBar.frame = CGRect(x: 0, y: 50, width: 320, height: height)
        toolBar.barStyle = .black
        toolBar.tintColor = .white
        toolBar.barTintColor = UIColor.blue

        let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(onToolbarDoneClick(sender:)) )
        let flexibleSpaceItem = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil )

        toolBar.setItems([flexibleSpaceItem, doneButton], animated: false)
        toolBar.isUserInteractionEnabled = true

        toolBar.sizeToFit()
        return toolBar
    

    @objc func onToolbarDoneClick(sender: UIBarButtonItem) 
        webView?.resignFirstResponder()
    



var ToolbarHandle: UInt8 = 0

extension WKWebView 

    func addInputAccessoryView(toolbar: UIView?) 
        guard let toolbar = toolbar else return
        objc_setAssociatedObject(self, &ToolbarHandle, toolbar, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)

        var candidateView: UIView? = nil
        for view in self.scrollView.subviews 
            let description : String = String(describing: type(of: view))
            if description.hasPrefix("WKContent") 
                candidateView = view
                break
            
        
        guard let targetView = candidateView else return
        let newClass: AnyClass? = classWithCustomAccessoryView(targetView: targetView)

        guard let targetNewClass = newClass else return

        object_setClass(targetView, targetNewClass)
    

    func classWithCustomAccessoryView(targetView: UIView) -> AnyClass? 
        guard let _ = targetView.superclass else return nil
        let customInputAccesoryViewClassName = "_CustomInputAccessoryView"             

        var newClass: AnyClass? = NSClassFromString(customInputAccesoryViewClassName)
        if newClass == nil 
            newClass = objc_allocateClassPair(object_getClass(targetView), customInputAccesoryViewClassName, 0)
         else 
            return newClass
        

        let newMethod = class_getInstanceMethod(WKWebView.self, #selector(WKWebView.getCustomInputAccessoryView))
        class_addMethod(newClass.self, #selector(getter: WKWebView.inputAccessoryView), method_getImplementation(newMethod!), method_getTypeEncoding(newMethod!))

        objc_registerClassPair(newClass!)

        return newClass
    

    @objc func getCustomInputAccessoryView() -> UIView? 
        var superWebView: UIView? = self
        while (superWebView != nil) && !(superWebView is WKWebView) 
            superWebView = superWebView?.superview
        

        guard let webView = superWebView else return nil

        let customInputAccessory = objc_getAssociatedObject(webView, &ToolbarHandle)
        return customInputAccessory as? UIView
    

【讨论】:

我们可以让键盘外观变暗吗?【参考方案2】:
private var keyBordView: UIView?


override func viewDidLoad() 
    super.viewDidLoad()


    let webView = WKWebView.init(frame: view.bounds)
    webView.loadhtmlString("<html><body><div contenteditable='true'></div></body></html>", baseURL: nil)
    view.addSubview(webView)
    for subview in webView.scrollView.subviews 
        if subview.classForCoder.description() == "WKContentView" 
            keyBordView = subview
        
    

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow), name: .UIKeyboardDidShow, object: nil)

    // Do any additional setup after loading the view.



@objc private func keyboardShow() 

    let keyboardToolbar = UIToolbar()
    keyboardToolbar.backgroundColor = UIColor.blue
    keyboardToolbar.sizeToFit()
    let flexBarButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    let doneBarButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.dismissKeyBord))
    keyboardToolbar.items = [flexBarButton, doneBarButton]
    keyBordView = keyboardToolbar

【讨论】:

您确定要写入 keyBoardView.inputAccessoryView 吗?那不是只读的吗? @Viktor_DE 让我检查一下 这也不行。我用新的外观属性代码更新了我的问题。 遇到同样的问题,@Viktor_DE 你找到解决方案了吗? @Delorean 不,我找不到任何解决此问题的方法,我不得不稍微更改页面颜色以匹配我得到的淡蓝色结果...

以上是关于如何编辑从 WKWebView 显示的键盘附件视图?的主要内容,如果未能解决你的问题,请参考以下文章

在 WKWebView 中按 Return 键关闭键盘

iPhone - 向键盘现有附件视图添加一个按钮(来自 UIWebView 的键盘)

输入附件视图行为异常与键盘隐藏和显示事件

键盘可见时,将输入附件视图添加到UITextField

防止由键盘输入附件视图引起的表格视图动画

显示键盘时,WKWebView会出现约束问题