ios - 如何编辑从 WKWebView 显示的键盘附件视图?
问题描述
我在我的 Swift 应用程序中使用 WKWebView 来呈现一些文本字段。
我设置了一些外观属性来匹配特定的设计,在这种情况下,它的背景必须是蓝色的。但是当 WKWebView 触发键盘时,它对外观属性做了一些事情,并以我的颜色的淡光外观显示键盘工具栏,你知道为什么吗?
UIToolBar 上唯一有效的外观操作是这个:
UIToolbar.appearance().backgroundColor = .blue
解决方案
找到了一种方法,最终调配了 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
}
}
推荐阅读
- vuejs3 - VueJS 的多选组件
- javascript - 将来自后端的日期与 javascript 时间进行比较
- flutter - 更新 UI 时出错,setState() 无法正常工作
- arrays - 具有多个自动生成的 importxml 查询的列表
- javascript - React Native Paper ProgressBar 不可见
- r - 如何在R中的函数中打印变量名
- python - 在 pandas 中使用 if-condition 填充 pandas 中的 na 值
- python - 减少 pandas groupby 函数的内存占用
- python - 英特尔模型动物园的 launch_benchmark.py 因 resnet34 失败
- java - 如何管理 WebSocket 端点中的线程?