1. 程式人生 > >WKWebView新特性及JS互動

WKWebView新特性及JS互動

本部落格不會在此處更新文章,請關注微信公眾號,更新的內容只會是在原文更新。

引言

一直聽說WKWebViewUIWebView強大許多,可是一直沒有使用到,今天花了點時間看寫了個例子,對其API的使用有所瞭解,為了日後能少走彎路,也為了讓大家更容易學習上手,這裡寫下這篇文章來記錄如何使用以及需要注意的地方。

溫馨提示:本人在學習使用過程中,確實有此體會,WKWebView的確比UIWebView強大很多,與JS互動的能力顯示增強,在載入速度上有所提升。

WKWebView新特性

  • 效能、穩定性、功能大幅度提升
  • 允許JavaScript的Nitro庫載入並使用(UIWebView中限制)
  • 支援了更多的HTML5特性
  • 高達60fps的滾動重新整理率以及內建手勢
  • GPU硬體加速
  • KVO
  • 重構UIWebView成14類與3個協議,檢視官方文件

準備工作

首先,我們在使用的地方引入模組:

<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> Webkit</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

在學習之前,建議大家先點選WKWebView進去閱讀裡面的相關API,讀完一遍,有個大概的印象,學習起來就很快了。

其初始化方法有:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>()
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>(frame: CGRect)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">init</span>(frame: CGRect, configuration: WKWebViewConfiguration)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

載入HTML的方式與UIWebView的方式大致相同。其中,loadFileURL方法通常用於載入伺服器的HTML頁面或者JS,而loadHTMLString方法通常用於載入本地HTML或者JS:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> func loadRequest(request: NSURLRequest) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>WKNavigation<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">?</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 9.0以後才支援   </span>
@available(iOS <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9.0</span>, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> func loadFileURL(URL: NSURL, allowingReadAccessToURL readAccessURL: NSURL) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>WKNavigation<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">?</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 通常用於載入本地HTML或者JS</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> func loadHTMLString(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">string</span>: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, baseURL: NSURL<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">?</span>) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>WKNavigation<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">?</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 9.0以後才支援</span>
@available(iOS <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">9.0</span>, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> func loadData(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span>: NSData, MIMEType: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, characterEncodingName: <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">String</span>, baseURL: NSURL) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-> </span>WKNavigation</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li></ul>

與之互動用到的三大代理:

  • WKNavigationDelegate,與頁面導航載入相關
  • WKUIDelegate,與JS互動時的ui展示相關,比較JS的alert、confirm、prompt
  • WKScriptMessageHandler,與js互動相關,通常是ios端注入名稱,js端通過window.webkit.messageHandlers.{NAME}.postMessage()來發訊息到ios端

建立WKWebView

首先,我們在ViewController中先遵守協議:

<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">ViewController</span>: <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">UIViewController</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">WKScriptMessageHandler</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">WKNavigationDelegate</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">WKUIDelegate</span></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

我們可以先建立一個WKWebView的配置項WKWebViewConfiguration,這可以設定偏好設定,與網頁互動的配置,注入物件,注入js等:

<code class="hljs rust has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 建立一個webiview的配置項</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> configuretion = WKWebViewConfiguration()

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// Webview的偏好設定</span>
configuretion.preferences = WKPreferences()
configuretion.preferences.minimumFontSize = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10</span>
configuretion.preferences.javaScriptEnabled = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 預設是不能通過JS自動開啟視窗的,必須通過使用者互動才能開啟</span>
configuretion.preferences.javaScriptCanOpenWindowsAutomatically = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 通過js與webview內容互動配置</span>
configuretion.userContentController = WKUserContentController()

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 新增一個JS到HTML中,這樣就可以直接在JS中呼叫我們新增的JS方法</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">let</span> script = WKUserScript(source: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"function showAlert() { alert('在載入webview時通過Swift注入的JS方法'); }"</span>,
  injectionTime: .AtDocumentStart,<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 在載入時就新增JS</span>
  forMainFrameOnly: <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>) <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 只新增到mainFrame中</span>
configuretion.userContentController.addUserScript(script)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 新增一個名稱,就可以在JS通過這個名稱傳送訊息:</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// window.webkit.messageHandlers.AppModel.postMessage({body: 'xxx'})</span>
configuretion.userContentController.addScriptMessageHandler(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, name: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"AppModel"</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>

建立物件並遵守代理:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span> = WKWebView(frame: self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.bounds</span>, configuration: configuretion)

self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.navigationDelegate</span> = self
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.UIDelegate</span> = self</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

載入我們的本地HTML頁面:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">let url = NSBundle<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.mainBundle</span>()<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.URLForResource</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"test"</span>, withExtension: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"html"</span>)
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.loadRequest</span>(NSURLRequest(URL: url!))
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addSubview</span>(self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span>)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

我們再新增前進、後退按鈕和新增一個載入進度的控制顯示在Webview上:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.progressView</span> = UIProgressView(progressViewStyle: <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Default</span>)
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.progressView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.frame</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.size</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.width</span> = self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.frame</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.size</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.width</span>
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.progressView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.backgroundColor</span> = UIColor<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.redColor</span>()
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.addSubview</span>(self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.progressView</span>)

self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.navigationItem</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.leftBarButtonItem</span> = UIBarButtonItem(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"上一個頁面"</span>, style: <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Done</span>, target: self, action: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"previousPage"</span>)
self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.navigationItem</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.rightBarButtonItem</span> = UIBarButtonItem(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"下一個頁面"</span>, style: <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.Done</span>, target: self, action: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"nextPage"</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

頁面前進、後退

對於前進後退的事件處理就很簡單的,要注意判斷一下是否可以後退、前進才呼叫:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">func previousPage() {
    if self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.canGoBack</span> {
      self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.goBack</span>()
    }
}

func nextPage() {
    if self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.canGoForward</span> {
      self<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.webView</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.goForward</span>()
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>

當然除了這些方法之處,還有重新載入等。

WKWebView的KVO

對於WKWebView,有三個屬性支援KVO,因此我們可以監聽其值的變化,分別是:loading,title,estimatedProgress,對應功能表示為:是否正在載入中,頁面的標題,頁面內容載入的進度(值為0.0~1.0)

<code class="hljs php has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 監聽支援KVO的屬性</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.webView.addObserver(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, forKeyPath: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"loading"</span>, options: .<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">New</span>, context: nil)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.webView.addObserver(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, forKeyPath: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"title"</span>, options: .<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">New</span>, context: nil)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.webView.addObserver(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>, forKeyPath: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"estimatedProgress"</span>, options: .<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">New</span>, context: nil)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>

然後就可以重寫監聽的方法來處理。這裡只是取頁面的標題,更新載入的進度條,在載入完成時,手動呼叫執行一個JS方法:

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">MARK</span>: - KVO
override func observeValueForKeyPath(<span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">keyPath</span>: String?, ofObject <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">object</span>: AnyObject?, <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">change</span>: [String : AnyObject]?, <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">context</span>: UnsafeMutablePointer<Void>) {
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> keyPath == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"loading"</span> {
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"loading"</span>)
  } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> keyPath == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"title"</span> {
    self.title = self.webView.title
  } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> keyPath == <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"estimatedProgress"</span> {
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(webView.estimatedProgress)
    self.progressView.setProgress(Float(webView.estimatedProgress), <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">animated</span>: <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>)
  }

  <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 已經完成載入時,我們就可以做我們的事了
  <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> !webView.loading {
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 手動呼叫JS程式碼
    <span class="hljs-reserved" style="box-sizing: border-box;">let</span> js = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"callJsAlert()"</span>;
    self.webView.evaluateJavaScript<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(js)</span> { <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(_, _)</span> -></span> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
      <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">print</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"call js alert"</span>)
    }

    UIView.animateWithDuration<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.55</span>, animations: { () -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
      self.progressView.alpha = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0.0</span>;
    })</span>
  }
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

WKUIDelegate

我們看看WKUIDelegate的幾個代理方法,雖然不是必須實現的,但是如果我們的頁面中有呼叫了js的alert、confirm、prompt方法,我們應該實現下面這幾個代理方法,然後在原來這裡呼叫native的彈出窗,因為使用WKWebView後,HTML中的alert、confirm、prompt方法呼叫是不會再彈出視窗了,只是轉化成ios的native回撥代理方法:

<code class="hljs coffeescript has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(0, 136, 0);">MARK</span>: - WKUIDelegate
<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 這個方法是在HTML中呼叫了JS的alert()方法時,就會回撥此API。
<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 注意,使用了`<span class="javascript" style="box-sizing: border-box;">WKWebView</span>`後,在JS端呼叫alert()就不會在HTML
<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 中顯示彈出視窗。因此,我們需要在此處手動彈出ios系統的alert。
func webView<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: () -> Void)</span> {
  <span class="hljs-title" style="box-sizing: border-box;">let</span> <span class="hljs-title" style="box-sizing: border-box;">alert</span> = <span class="hljs-title" style="box-sizing: border-box;">UIAlertController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tip"</span>, message: message, preferredStyle: .Alert)</span>
  <span class="hljs-title" style="box-sizing: border-box;">alert</span>.<span class="hljs-title" style="box-sizing: border-box;">addAction</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(UIAlertAction(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ok"</span>, style: .Default, handler: { (_) -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> We must call back js
    completionHandler()
  }))</span>

  <span class="hljs-title" style="box-sizing: border-box;">self</span>.<span class="hljs-title" style="box-sizing: border-box;">presentViewController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(alert, animated: <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>, completion: nil)</span>
}

<span class="hljs-title" style="box-sizing: border-box;">func</span> <span class="hljs-title" style="box-sizing: border-box;">webView</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: (Bool) -> Void)</span> {
  <span class="hljs-title" style="box-sizing: border-box;">let</span> <span class="hljs-title" style="box-sizing: border-box;">alert</span> = <span class="hljs-title" style="box-sizing: border-box;">UIAlertController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Tip"</span>, message: message, preferredStyle: .Alert)</span>
  <span class="hljs-title" style="box-sizing: border-box;">alert</span>.<span class="hljs-title" style="box-sizing: border-box;">addAction</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(UIAlertAction(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ok"</span>, style: .Default, handler: { (_) -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 點選完成後,可以做相應處理,最後再回調js端
    completionHandler(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>)
  }))</span>
  <span class="hljs-title" style="box-sizing: border-box;">alert</span>.<span class="hljs-title" style="box-sizing: border-box;">addAction</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(UIAlertAction(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Cancel"</span>, style: .Cancel, handler: { (_) -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
    <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 點選取消後,可以做相應處理,最後再回調js端
    completionHandler(<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">false</span>)
  }))</span>

  <span class="hljs-title" style="box-sizing: border-box;">self</span>.<span class="hljs-title" style="box-sizing: border-box;">presentViewController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(alert, animated: <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>, completion: nil)</span>
}

<span class="hljs-title" style="box-sizing: border-box;">func</span> <span class="hljs-title" style="box-sizing: border-box;">webView</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: (String?) -> Void)</span> {
  <span class="hljs-title" style="box-sizing: border-box;">let</span> <span class="hljs-title" style="box-sizing: border-box;">alert</span> = <span class="hljs-title" style="box-sizing: border-box;">UIAlertController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(title: prompt, message: defaultText, preferredStyle: .Alert)</span>

  <span class="hljs-title" style="box-sizing: border-box;">alert</span>.<span class="hljs-title" style="box-sizing: border-box;">addTextFieldWithConfigurationHandler</span> { <span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(textField: UITextField)</span> -></span> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
    textField.textColor = UIColor.redColor()
  }
  alert.addAction<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(UIAlertAction(title: <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Ok"</span>, style: .Default, handler: { (_) -> Void <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span>
     <span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">//</span> 處理好之前,將值傳到js端
    completionHandler(alert.textFields![<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].text!)
  }))</span>

  <span class="hljs-title" style="box-sizing: border-box;">self</span>.<span class="hljs-title" style="box-sizing: border-box;">presentViewController</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(alert, animated: <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">true</span>, completion: nil)</span>
}

<span class="hljs-title" style="box-sizing: border-box;">func</span> <span class="hljs-title" style="box-sizing: border-box;">webViewDidClose</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(webView: WKWebView)</span> {
  <span class="hljs-title" style="box-sizing: border-box;">print</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(__FUNCTION__)</span>
}</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; paddi