WKWebViewで、JavaScriptから「別窓・ポップアップが表示されない」と言われたときの対処
Table of Contents
ポップアップが表示されないと言われたときの可能性 #
ポップアップにも色々ありますが、ここでは「リンクをタップするなどして、別ウィンドウで表示すること」のこととしています。
大抵の場合は target="_blank"
のリンクだな……と推測できます。
しかしながら、そのウィンドウを開くイベントがJavaScriptから発生した場合は、別途、WKWebView側に設定する必要がありました……。
JavaScriptからウィンドウを開けるようにする #
WKWebViewに対して、以下の設定をする必要がありました。
let preferences = WKPreferences()
preferences.javaScriptCanOpenWindowsAutomatically = true // ここが重要
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
webView = WKWebView(frame: .zero, configuration: configuration)
これで、JavaScriptから新しいタブを開けるようになりました。
新しいWebViewを開かずに、既存のWebViewで読み込ませる #
アプリ内で使用しているWKWebViewでは「新しいタブ」をサポートできない場合もあります。
その場合は、 target=_blank
のときと同じようにWKUIDelegateを、以下のように実装します。
メソッドの引数が多いので、改行しています。
extension MyWebViewViewController: WKUIDelegate {
func webView(_ webView: WKWebView,
createWebViewWith configuration: WKWebViewConfiguration,
for navigationAction: WKNavigationAction,
windowFeatures: WKWindowFeatures) -> WKWebView? {
guard let url = navigationAction.request.url else { return nil }
guard let targetFrame = navigationAction.targetFrame, targetFrame.isMainFrame else {
let request = URLRequest(url: url)
webView.load(url)
return nil
}
return nil
}
}
本来は新しいタブを開くときに呼ばれるメソッド(返り値がWKWebViewになっている)ですが、 ここでは、すでにあるWebViewで読み込むように実装し、新しいWebViewは返さないようにしています。
あとは、この実装したWKUIDelegateを、webViewにセットしておけばOK。
webView.uiDelegate = self // selfにWKUIDelegateを実装している場合
これで完成!
ブラウザなら当たり前にできると思っていることも、アプリのWebViewで対応するときは手作業で設定するものが多いですね……。 しかも意外と、そのオプションたちに気づきにくいという……。