目录
WKWebview 在ios8.0系统以后苹果推出的新控件,用于解决uiwebview的卡顿、占内存等一些列问题。此外对h5,js处理也比较友好,今天总结一下自己了解的部分备用:
一、生成webview:
需要倒入webkit框架,初始化,加载、暂停、后退、刷新等和uiwebview一致:
let webView = WKWebView()
override func viewDidLoad() {
super.viewDidLoad()
initSubView()
let req = URLRequest.init(url: URL.init(string: "https://passport.baidu.com/v2/?login")!)
webView.load(req)
// webView.loadFileURL(<#T##URL: URL##URL#>, allowingReadAccessTo: <#T##URL#>) //webview加载本地文件
// webView.loadHTMLString(<#T##string: String##String#>, baseURL: <#T##URL?#>) //webview加载html字符串
webView.navigationDelegate = self
webView.uiDelegate = self
// webView.allowsBackForwardNavigationGestures = false. //水平swip手势是否影响webview加载
// Do any additional setup after loading the view, typically from a nib.
}
@IBAction func stop(_ sender: Any) {
webView.stopLoading()
}
@IBAction func refresh(_ sender: Any) {
webView.reload()
}
// webView.goBack()
//webView.goForward()
此外新增执行js代码
let meta = "document.getElementsByName(\"viewport\")[0].content = \"width=self.view.frame.size.width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no\""
webView.evaluateJavaScript(meta, completionHandler: nil)
二、代理
wkwebview共有两个代理:WKNavigationDelegate主要处理数据加载,基本包含处理以前uiwebview代理内容。WKUIDelegate处理页面切换方式
2.1 WKNavigationDelegate下面简单说下代理里面的方法:
extension ViewController : WKNavigationDelegate{
// webview 内容准备绘制到view时调用
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
print(#function)
}
//wwebview 内容准备要加载到view时调用
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print(#function)
}
//服务器重定向时调用
func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
print(#function)
}
//url 需要认证时调用
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// print(#function)
if let trust = challenge.protectionSpace.serverTrust{
let card = URLCredential.init(trust: trust)
completionHandler(.useCredential,card)
}else{
completionHandler(.rejectProtectionSpace,nil)
}
}
//http请求会执行这个失败,但不影响显示
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print(#function)
}
//webview 加载内容失败
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
print(#function)
}
//webview 加载完成
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print(#function)
}
//web view 进程终止,测试时未执行过
func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
print(#function)
}
//确认一个超链接是否跳转,可以自定义跳转方式。 超链接点击时执行
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if let url = navigationAction.request.url{
let sa = SFSafariViewController.init(url:url)
self.show(sa, sender: nil)
decisionHandler(.cancel)
}else{
decisionHandler(.allow)
}
}
// 确认一个超链接是否跳转,可以自定义跳转方式。 超链接点击请求返回时执行,若handle 。cancel 加载失败的代理方法会执行一次
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
if let url = navigationResponse.response.url{
let sa = SFSafariViewController.init(url:url)
self.show(sa, sender: nil)
decisionHandler(.cancel)
}else{
decisionHandler(.allow)
}
}
}
2.2WKUIDelegate
extension ViewController: WKUIDelegate{
/// js 弹框替换成iOS原生的三个方法
//执行js alert方法时调用
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
print(#function)
//自定义弹框展示
completionHandler() //确认事件中执行
}
//执行js confirm方法时调用
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
print(#function)
//自定义弹框展示
// completionHandler(true) //确认事件中执行
// completionHandler(false)//确认事件中执行
}
//执行js prompt方法时调用
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
print(#function)
//自定义弹框展示 // completionHandler("sss")
// eg:
// let alert = UIAlertController.init(title: "", message: "", preferredStyle: UIAlertControllerStyle.alert).addTextField { (field) in
// completionHandler(field.text)//确认事件中执行
// }
// self.show(alert, sender: nil)
}
//webview关闭时调用
func webViewDidClose(_ webView: WKWebView) {
print(#function)
}
//创建新的webview
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
print(#function)
let view = WKWebView.init(frame: webView.frame, configuration: configuration)
// view.load(navigationAction.request)
return view
}
//确认webview应不应该展示预览页面
func webView(_ webView: WKWebView, shouldPreviewElement elementInfo: WKPreviewElementInfo) -> Bool {
print(#function)
return true
}
//如果展示预览页面 这一步生成此vc预览页面,接下来调用生成webview代理,进而生成页面
func webView(_ webView: WKWebView, previewingViewControllerForElement elementInfo: WKPreviewElementInfo, defaultActions previewActions: [WKPreviewActionItem]) -> UIViewController? {
print(#function)
return UIViewController()
}
//当预览页面消失时调用
func webView(_ webView: WKWebView, commitPreviewingViewController previewingViewController: UIViewController) {
print(#function)
}
}