【问题标题】:How to implement WKUIDelegate into SwiftUI WKWebView?如何在 SwiftUI WKWebView 中实现 WKUIDelegate?
【发布时间】:2019-12-17 21:18:36
【问题描述】:

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

我在 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 Alert 和 Confirm。

【问题讨论】:

    标签: swift swiftui wkwebview


    【解决方案1】:

    你需要使用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(..)uiDelegate 设置为context.coordinator

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

    如果您想符合WKNavigationDelegate,则符合它并将navigationDelegate 设置为context.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()
        }
    }
    

    【讨论】:

    • 非常感谢您的回复!因为我以前没有真正使用过 Swift,所以我不确定如何将你的代码实现到我现有的代码中,哈哈,我可以将我的代码添加到你有评论“代码在这里”的地方吗?
    • @Ohsik 我用完整的代码更新了答案以及它的去向。
    • 非常感谢。我添加了您的代码,但仍不确定如何添加警报功能。我的警报和确认是通过 Javascript 在网络应用程序上控制的。这将如何与 Swift 交互?
    • @Ohsik 我建议您接受这个作为您现有问题的正确答案,然后再提出一个关于如何实现警报功能的单独问题。
    • 为函数stackoverflow.com/questions/59384352/…创建了一个新问题
    猜你喜欢
    • 2020-02-11
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多