在 userContentController 中启动/更新视图 - 功能

Start / update View in userContentController - Function

我尝试通过单击按钮在 WKWebview 的帮助下启动第二个视图。 它也有效。我在函数 userContentController 中得到一个回调。如何通过此功能在应用程序中启动新视图。

struct MyWebView: UIViewRepresentable {

    var webPageURL = "https://google.de"

    func updateUIView(_ uiView: WKWebView, context: Context) {
        let myURL = URL(string:webPageURL)
        let myRequest = URLRequest(url: myURL!)
        uiView.load(myRequest)
    }

    func makeUIView(context: Context) -> WKWebView {

        let webConfiguration = WKWebViewConfiguration()
        let wkcontentController = WKUserContentController()

        wkcontentController.add(context.coordinator, name: "doStuffMessageHandler")
        webConfiguration.userContentController = wkcontentController

        let webView = WKWebView(frame: .zero,configuration: webConfiguration)
        context.coordinator.parent = webView // inject as weak

        return webView
    }

    func makeCoordinator() -> ContentController {
         ContentController() // let handler be a coordinator
     }
}

class ContentController: NSObject, WKScriptMessageHandler {
    weak var parent: WKWebView? // weak to avoid reference cycling


     func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
     {
        if message.name == "doStuffMessageHandler"
        {

            print(message.body)

        }
    }
}

struct MyWebView_Previews: PreviewProvider {
    static var previews: some View {
        MyWebView()
    }
}

可能的解决方案是使用通知(允许保持这些组件独立)。

extension Notification.Name {
    static let didReceiveMessage = Notification.Name("didReceiveMessage")
}

class ContentController: NSObject, WKScriptMessageHandler {
    weak var parent: WKWebView? // weak to avoid reference cycling

     func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
     {
        if message.name == "doStuffMessageHandler"
        {
            NotificationCenter.default.post(name: .didReceiveMessage, object: message.body)
        }
    }
}

struct DemoHandleMessage: View {
    @State private var showMessage = false
    @State private var message: String? = nil
    var body: some View {
        VStack {
            if showMessage {
                 // switch back via bound flag to showMessage state
                MessageView(text: message, dismiss: $showMessage)
            } else {
                MyWebView()
            }
        }.onReceive(NotificationCenter.default.publisher(for: .didReceiveMessage)) { notification in
            self.message = notification.object as? String
            self.showMessage = true
        }
    }
}