はじめに
【SwiftUI】WKWebViewを使えるようにする - Swift・iOSに記載した実装内容を修正して、WKWebView用のボタン(戻る/進む/再読み込み)を設置してみたので記事に残します。
開発環境
- macOS Big Sur 11.2.3
- Xcode 12.4
- Swift 5.3.2
実装
WebView.swift
import SwiftUI import WebKit struct WebView: UIViewRepresentable { var webView = WKWebView() var urlString: String class Coordinator: NSObject, WKUIDelegate, WKNavigationDelegate { var parent: WebView init(_ parent: WebView) { self.parent = parent } // "target="_blank""が設定されたリンクも開けるようにする func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { if navigationAction.targetFrame == nil { webView.load(navigationAction.request) } return nil } // URLごとに処理を制御する func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url?.absoluteString { if (url.hasPrefix("https://apps.apple.com/")) { guard let appStoreLink = URL(string: url) else { return } UIApplication.shared.open(appStoreLink, options: [:], completionHandler: { (succes) in }) decisionHandler(WKNavigationActionPolicy.cancel) } else if (url.hasPrefix("http")) { decisionHandler(WKNavigationActionPolicy.allow) } else { decisionHandler(WKNavigationActionPolicy.cancel) } } } // 表示しているページ情報 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { // 表示しているページのURL print(webView.url?.absoluteString ?? "") // 表示しているページのタイトル print(webView.title ?? "") } } func makeCoordinator() -> Coordinator { Coordinator(self) } func makeUIView(context: Context) -> WKWebView { return webView } func updateUIView(_ webView: WKWebView, context: Context) { // makeCoordinatorで生成したCoordinatorクラスのインスタンスを指定 webView.uiDelegate = context.coordinator webView.navigationDelegate = context.coordinator // スワイプで画面遷移できるようにする webView.allowsBackForwardNavigationGestures = true guard let url = URL(string: urlString) else { return } let request = URLRequest(url: url) webView.load(request) } // 前のページに戻る func goBack() { webView.goBack() } // 次のページに進む func goForward() { webView.goForward() } // ページをリロードする func reload() { webView.reload() } }
ContentView.swift(WebViewの使用例)
import SwiftUI struct ContentView: View { private var webView = WebView(urlString: "{表示したいURL}") var body: some View { VStack() { webView HStack { Spacer() Button(action: { webView.goBack() }) { Image(systemName: "chevron.backward") } .font(.title3) .padding(15) Spacer() Button(action: { webView.goForward() }) { Image(systemName: "chevron.forward") .font(.title3) .padding(15) } Spacer() Button(action: { webView.reload() }) { Image(systemName: "arrow.counterclockwise") .font(.title3) .padding(15) } Spacer() } .background(Color(red: 0.9, green: 0.9, blue: 0.9)) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
おわりに
簡単に実装できるとはいえ、UIViewRepresentableを使わなくてもSwiftUIでWKWebView使えるようになってほしい・・・。