首页 > 解决方案 > 如何在 SwiftUI WKWebView 中实现 WKUIDelegate?

问题描述

我正在 Xcode v11 上创建一个 Web 应用程序,并且在实现 WKUIDelegate 以显示 Javascript 警报并在 Web 应用程序上正确确认时遇到问题。

我在 ContentView.swift 上有一个非常简单的 webview 应用程序,其中包含以下代码,但不确定如何WKUIDelegate使用此代码正确实现。

import SwiftUI
import WebKit

struct Webview : UIViewRepresentable {
    let request: URLRequest
    var webview: WKWebView?

    init(web: WKWebView?, req: URLRequest) {
        self.webview = WKWebView()
        self.request = req
    }

    func makeUIView(context: Context) -> WKWebView  {
        return webview!
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.load(request)
    }

    func goBack(){
        webview?.goBack()
    }

    func goForward(){
        webview?.goForward()
    }

    func reload(){
        webview?.reload()
    }
}

struct ContentView: View {

    let webview = Webview(web: nil, req: URLRequest(url: URL(string: "https://google.com")!))

    var body: some View {
        VStack {
            webview
            HStack() {
                Button(action: {
                    self.webview.goBack()
                }){
                    Image(systemName: "chevron.left")
                }.padding(32)

                Button(action: {
                    self.webview.reload()
                }){
                    Image(systemName: "arrow.clockwise")
                }.padding(32)

                Button(action: {
                    self.webview.goForward()
                }){
                    Image(systemName: "chevron.right")
                }.padding(32)
            }.frame(height: 32)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

实现WKUIDelegate此代码的最佳方法是什么?因此,它将正确显示 Javascript 警报和确认。

标签: swiftswiftuiwkwebview

解决方案


您需要使用Coordinator然后符合WKUIDelegate

class Coordinator: NSObject, WKUIDelegate {
    var parent: Webview

    init(_ parent: Webview) {
        self.parent = parent
    }

    // Delegate methods go here
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        // alert functionality goes here
    }
}

func makeCoordinator() -> Coordinator {
    Coordinator(self)
}

然后确保您updateUIView(..)将设置设置uiDelegatecontext.coordinator

func updateUIView(_ uiView: WKWebView, context: Context) {
    uiView.uiDelegate = context.coordinator
    [...]
}

如果你想符合WKNavigationDelegate然后符合它并设置navigationDelegatecontext.coordinator以及。

完整代码在这里:

import SwiftUI
import WebKit

struct Webview : UIViewRepresentable {
    let request: URLRequest
    var webview: WKWebView?

    init(web: WKWebView?, req: URLRequest) {
        self.webview = WKWebView()
        self.request = req
    }

    class Coordinator: NSObject, WKUIDelegate {
        var parent: Webview

        init(_ parent: Webview) {
            self.parent = parent
        }

        // Delegate methods go here

        func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
            // alert functionality goes here
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> WKWebView  {
        return webview!
    }

    func updateUIView(_ uiView: WKWebView, context: Context) {
        uiView.uiDelegate = context.coordinator
        uiView.load(request)
    }

    func goBack(){
        webview?.goBack()
    }

    func goForward(){
        webview?.goForward()
    }

    func reload(){
        webview?.reload()
    }
}

推荐阅读