Project4-WKWebView, WKNavigationDelegate, KVO, @esacping

1.利用WKWebView在app內嵌入網頁
在loadView()中設置view

override func loadView() {
    webView = WKWebView()
    webView.navigationDelegate = self
    view = webView
}

2.加載頁面方法

let url = URL(string: "https://www.baidu.com")!
webView.load(URLRequest(url: url))
//允許右滑返回的手勢
webView.allowsBackForwardNavigationGestures = true 

3.WKNavigationDelegate
頁面跳轉的代理方法

//發送請求之前決定是否跳轉
optional public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void)
//收到響應之后決定是否跳轉
optional public func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void)
// 接收到服務器跳轉請求之后調用
optional public func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!)

加載的狀態回調

//頁面開始加載時候調用
optional public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
//頁面內容開始返回的時候調用
optional public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!)
//加載完成后調用
optional public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)
//加載失敗后調用
optional public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error)

4.利用KVO監測webView加載的進度
添加觀察器

webView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)

實現監測方法

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if keyPath == #keyPath(WKWebView.estimatedProgress) {
        progressView.progress = Float(webView.estimatedProgress)
    }
}

移除觀察器

deinit {
        webView.removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress))
    }
  1. @escaping 和@noesacpe注解
func hostFunc(@noescape closure: () -> ()) -> Void {
    //以下編譯出錯, closure 被修飾后, 不能被其他異步線程捕獲
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
        closure()
    }
}

@noescape字面意思是無法逃脫. 在上例中, closure 被@noescape修飾, 則聲明 closure 的生命周期不能超過 hostFunc, 并且, closure不能被hostFunc中的其他閉包捕獲

@escaping就是可以逃逸的意思,在當前func執行完畢的時候并不影響這個閉包的執行。

[參考文章] https://swiftunboxed.com/lang/closures-escaping-noescape-swift3/?utm_campaign=This+Week+in+Swift&utm_medium=email&utm_source=This_Week_in_Swift_101

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容