我正在使用WKWebView打开example.com,在那里我有一个测试链接,它应该打开一个JS警报,但我无法让它显示在设备上,它只有在我查看网站时才有效来自浏览器.
我正在使用WKUIDelegate,并将这段代码添加到ViewController.swift文件中:
func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: (() -> Void)) { NSLog("Hello") }
当我点击产生JS警报的链接时,我在XCode控制台中看不到任何内容.
我错过了什么?
有点晚了,但我想补充一下我的经验,以备将来参考.当我尝试使用Swift 3和IOS 10时,@ Bon Bon的答案让我走上了解决方案的道路,在这种情况下,代码需要进行一些修改.首先,您还需要实现WKUIDelegate
,因此将其添加到ViewController
声明中:
class ViewController: UIViewController, WKUIDelegate {
然后在实例化WKWebView
对象时,例如:
self.webView = WKWebView(frame: self.view.frame)
您还需要uiDelegate
为实例的属性分配正确的值:
self.webView?.uiDelegate = self
最后你可以使用@Bon Bon提供的代码,但请注意Swift 3需要一些小的差异,例如,presentViewController
方法的名称变为present
:
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet) alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in completionHandler() })) self.present(alertController, animated: true, completion: nil) } func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) { let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet) alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in completionHandler(true) })) alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in completionHandler(false) })) self.present(alertController, animated: true, completion: nil) } func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) { let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .alert) alertController.addTextField { (textField) in textField.text = defaultText } alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in if let text = alertController.textFields?.first?.text { completionHandler(text) } else { completionHandler(defaultText) } })) alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in completionHandler(nil) })) self.present(alertController, animated: true, completion: nil) }
这样做alert
,confirmation
并在Xcode 8中没有任何编译器警告的情况下text input
正常工作.我不是专家Swift程序员,所以任何有关代码正确性的有用评论都将非常感激.WKWebView
您还需要在WKWebView上设置uiDelegate.
import UIKit import WebKit class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate { var wkWebView: WKWebView! public override func viewDidLoad() { super.viewDidLoad() wkWebView = WKWebView(frame: view.bounds, configuration: WKWebViewConfiguration()) wkWebView.uiDelegate = self wkWebView.navigationDelegate = self view.addSubview(wkWebView!) let url = URL(string: "https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_alert")! wkWebView.load(URLRequest(url: url)) } func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) { let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert) let title = NSLocalizedString("OK", comment: "OK Button") let ok = UIAlertAction(title: title, style: .default) { (action: UIAlertAction) -> Void in alert.dismiss(animated: true, completion: nil) } alert.addAction(ok) present(alert, animated: true) completionHandler() } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { wkWebView.evaluateJavaScript("alert('Hello from evaluateJavascript()')", completionHandler: nil) } }
对于confirm()
和prompt()
看到其他委托方法.
以下是Swift中各种javascript警报实现的示例代码:
这都是关于将javascript警报中的信息转换为本机UI,并调用completionHandler()将用户操作发送回javascript引擎.
func webView(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: () -> Void) { let alertController = UIAlertController(title: nil, message: message, preferredStyle: .ActionSheet) alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action) in completionHandler() })) self.presentViewController(alertController, animated: true, completion: nil) } func webView(webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: (Bool) -> Void) { let alertController = UIAlertController(title: nil, message: message, preferredStyle: .ActionSheet) alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action) in completionHandler(true) })) alertController.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action) in completionHandler(false) })) self.presentViewController(alertController, animated: true, completion: nil) } func webView(webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: (String?) -> Void) { let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .ActionSheet) alertController.addTextFieldWithConfigurationHandler { (textField) in textField.text = defaultText } alertController.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action) in if let text = alertController.textFields?.first?.text { completionHandler(text) } else { completionHandler(defaultText) } })) alertController.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action) in completionHandler(nil) })) self.presentViewController(alertController, animated: true, completion: nil) }