view - 在 userContentController 中启动/更新视图 - 功能
问题描述
我尝试通过单击按钮在 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
}
}
}
推荐阅读
- php - 仅当管理员登录并为 php 中的用户禁用时,我如何启用链接
- php - Cron 作业 - 更新产品
- node.js - 流星'找不到模块'加密'
- java - 在 android Studio 中使用 Firestore 数据库实现一对一聊天应用程序的逻辑是什么?
- python - 遍历python beautifulsoup中的多个div,输出到df然后是csv
- apache-spark - 如何拦截流事件(相当于StreamingListener)?
- git - 如何强制 git 使用 SSH 身份验证?
- javascript - 历史 pushState 抛出 Uncaught DOMException
- haskell - 禁止标准输出中的引号(hackerrank)
- flutter - 如何在 Flutter 中的所有平台(包括 Web)上播放音频